2012-10-11 25 views
14

साथ विभाजित इस रूबी 1.8.7 है, लेकिन 1.9.x के लिए के रूप में ही किया जाना चाहिएरूबी स्ट्रिंग regex

मैं उदाहरण के लिए एक स्ट्रिंग को विभाजित करने की कोशिश कर रहा हूँ:

a = "foo.bar.size.split('.').last" 
# trying to split into ["foo", "bar","split('.')","last"] 

असल में विभाजित आदेश में यह प्रतिनिधित्व करता है, मैं regexp साथ यह करने के लिए कोशिश कर रहा हूँ, लेकिन यकीन नहीं कैसे, विचार regexp

a.split(/[a-z\(\)](\.)[a-z\(\)]/) 

यहाँ समूहउपयोग करने की कोशिश का उपयोग किया गयाइसे विभाजित करने के लिए लेकिन यह अच्छा दृष्टिकोण नहीं लगता है।

+1

यह आपके विचार के जितना आसान नहीं है। – sawa

+1

@sawa: आपने एक प्रश्न बंद कर दिया क्योंकि आपको लगता है कि यह बहुत कठिन है? – iconoclast

+0

@iconoclast मुझे याद नहीं है, लेकिन आपके विचार के कारण नहीं। – sawa

उत्तर

23

मुझे लगता है कि यह यह करना होगा:

a.split(/\.(?=[\w])/) 

मैं नहीं जानता कि आप कितना regex के बारे में पता है, लेकिन (?=[\w]) एक अग्रदर्शी कि कहते हैं, "केवल बिंदु का मिलान करता है, तो अगले वर्ण एक पत्र है चरित्र का प्रकार "। एक लुकहेड वास्तव में उस पाठ को पकड़ नहीं लेगा जो इसे मेल खाता है। यह सिर्फ "दिखता है"। तो परिणाम वही है जो आप खोज रहे हैं:

> a.split(/\.(?=[\w])/) 
=> ["foo", "bar", "size", "split('.')", "last"] 
+0

वाह, उत्कृष्ट और lookahead के बारे में जानकारी के लिए धन्यवाद। नहीं, मुझे यह नहीं पता था और सीखना उत्कृष्ट बात है बहुत उपयोगी लगता है। –

+1

आपका स्वागत है। यह साइट कमाल है: http://www.regular-expressions.info/ –

+1

यह एक स्ट्रिंग को "foo.bar.size.split ('bar') जैसे विभाजित करेगा। अंतिम" ''' 'foo" में, "बार", "आकार", "विभाजन ('", "बार')", "अंतिम"] '। – sawa

2

यहां मेरे पास रूबी एनवी नहीं है। मैंने python re.split() के साथ प्रयास किया।

In : re.split("(?<!')\.(?!')",a) 
Out: ['foo', 'bar', 'size', "split('.')", 'last'] 

regex ऊपर नकारात्मक अग्रदर्शी और lookbehind, सुनिश्चित करें कि केवल "डॉट" के बीच एकल उद्धरण विभाजक के रूप में काम नहीं करेगा बनाने के लिए है।

बेशक, आपके द्वारा दिए गए उदाहरण के लिए, एक दिखने वाला या लुकहेड पर्याप्त है। आप अपनी आवश्यकता के लिए सही तरीका चुन सकते हैं।

+0

जैसा कि आपने देखा होगा, यह' ["के लिए सही तरीके से काम नहीं करेगा foo "," bar "," size "," split ('o.b') "," last "]'। – sawa

7

मुझे डर है कि नियमित अभिव्यक्ति आपको बहुत दूर नहीं ले जाएंगी। उदाहरण के लिए निम्नलिखित भाव (जो रूबी भी मान्य हैं)

"(foo.bar.size.split('.')).last" 
"(foo.bar.size.split '.').last" 
"(foo.bar.size.split '(.) . .(). .').last" 

समस्या है पर विचार करें, कि कॉल की सूची वास्तव में कॉल की एक पेड़ है। दृष्टि में सबसे आसान समाधान शायद एक रूबी पार्सर का उपयोग करें और अपनी आवश्यकताओं के अनुसार पार्स पेड़ को बदलने (इस उदाहरण हम रिकर्सिवली कॉल पेड़ में उतरते रहे हैं, एक सूची में कॉल सभा) के लिए है:

# gem install ruby_parser 
# gem install awesome_print 
require 'ruby_parser' 
require 'ap' 

def calls_as_list code 
    tree = RubyParser.new.parse(code) 

    t = tree 
    calls = [] 

    while t 
     # gather arguments if present 
     args = nil 
     if t[3][0] == :arglist 
      args = t[3][1..-1].to_a 
     end 
     # append all information to our list 
     calls << [t[2].to_s, args] 
     # descend to next call 
     t = t[1] 
    end 

    calls.reverse 
end 

p calls_as_list "foo.bar.size.split('.').last" 
#=> [["foo", []], ["bar", []], ["size", []], ["split", [[:str, "."]]], ["last", []]] 
p calls_as_list "puts 3, 4" 
#=> [["puts", [[:lit, 3], [:lit, 4]]]] 

और किसी भी इनपुट की पार्स पेड़ को दिखाने के लिए:

ap RubyParser.new.parse("puts 3, 4") 
संबंधित मुद्दे