2010-01-05 19 views
10

वहाँ स्ट्रिंग func:[sync] displayPTS से regex /func:\[sync\] displayPTS/ बनाने के लिए कोई तरीका है?स्ट्रिंग से नियमित अभिव्यक्ति बनाएं

इस सवाल के पीछे की कहानी मैं एक पाठ फ़ाइल में के खिलाफ खोज करने के लिए सर्वल स्ट्रिंग pattens है और मैं एक ही बात बार-बार लिखने के लिए नहीं करना चाहती है।

File.open($f).readlines.reject {|l| not l =~ /"#{string1}"/} 
File.open($f).readlines.reject {|l| not l =~ /"#{string2}"/} 

इसके बजाय, मैं काम करने के लिए एक समारोह करना चाहते हैं:

def filter string 
      #build the reg pattern from string 
      File.open($f).readlines.reject {|l| not l =~ pattern} 
    end 
    filter string1 
    filter string2 
+0

के बजाय अपने स्ट्रिंग परिवर्तित करने के लिए एक रेगेक्स, क्या कोई खोज फ़ंक्शन नहीं है जो * रेगेक्स को सर्वो के रूप में नहीं लेता है? – mpen

+0

@ मार्क, बहुत अच्छा मुद्दा! – pierrotlefou

उत्तर

20
s = "func:[sync] displayPTS" 
# => "func:[sync] displayPTS" 
r = Regexp.new(s) 
# => /func:[sync] displayPTS/ 
r = Regexp.new(Regexp.escape(s)) 
# => /func:\[sync\]\ displayPTS/ 
0

कैसे उपयोग करने के बारे %r{}:

my_regex = "func:[sync] displayPTS" 
File.open($f).readlines.reject { |l| not l =~ %r{#{my_regex}} } 
+0

वह वर्ग ब्रैकेट से बच नहीं पाएगा। 'File.open' और 'find_all' –

3

तार सिर्फ तार कर रहे हैं, तो आप उन्हें एक नियमित अभिव्यक्ति में जोड़ सकते हैं, जैसे:

targets = [ 
    "string1", 
    "string2", 
].collect do |s| 
    Regexp.escape(s) 
end.join('|') 
targets = Regexp.new(targets) 

और फिर:

lines = File.readlines('/tmp/bar').reject do |line| 
    line !~ target 
end 

s !~ regexpnot s =~ regexp के बराबर है, लेकिन पढ़ने में आसान है।

फ़ाइल को बंद किए बिना File.open का उपयोग करने से बचें। फ़ाइल तब तक खुली रहेगी जब तक कि हटाए गए फ़ाइल ऑब्जेक्ट को कचरा इकट्ठा नहीं किया जाता है, जो लंबे समय तक हो सकता है कि आपका प्रोग्राम फ़ाइल हैंडल से बाहर हो जाएगा। आप अधिक से अधिक करने की जरूरत है, तो बस, लाइनों को पढ़ने तो:

File.open(path) do |file| 
    # do stuff with file 
end 

रूबी ब्लॉक के अंत में फ़ाइल बंद हो जाएगा।

तुम भी सोच सकते हैं कि क्या find_all का उपयोग कर और एक सकारात्मक मैच आसान होगा अस्वीकार और एक नकारात्मक मिलान की तुलना में पढ़ने के लिए। कम नकारात्मक पाठक के मन माध्यम से जाना है, स्पष्ट कोड:

lines = File.readlines('/tmp/bar').find_all do |line| 
    line =~ target 
end 
+0

+1 आपका समाधान काम नहीं करेगा क्योंकि यह' सिंक 'के आस-पास के ब्रैकेट से बचता नहीं है, जबकि बॉब का समाधान करता है। – pierrotlefou

10

मैं बॉब का जवाब चाहते हैं, लेकिन सिर्फ अपने कीबोर्ड पर समय बचाने के लिए:

string = 'func:\[sync] displayPTS' 
/#{string}/ 
+0

के ब्लॉक फॉर्म के लिए –

+0

मुझे लगता है कि सवाल interpolated regexps बनाने के बारे में अधिक था, लेकिन उचित बिंदु। अद्यतन – trevorgrayson

संबंधित मुद्दे