2010-01-05 30 views
10

func:[sync] displayPTS dizesinden /func:\[sync\] displayPTS/ regex'ini oluşturmak için herhangi bir yol var mı?Dizgiden düzenli ifade oluşturma

Bu sorunun ardındaki öykü, bir metin dosyasında arama yapmak için serval string pattens'im olması ve aynı şeyi tekrar tekrar yazmak istemem.

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

Bunun yerine, işi yapmak için bir işlev istiyorum:

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

yerine sizin dize dönüştürme Bir regex, * bir parazit olarak bir regex almaz * bir arama fonksiyonu yok mu? – mpen

+0

@Mark, çok iyi bir nokta! – pierrotlefou

cevap

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

Nasıl %r{} kullanma hakkında:

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

Bu, köşeli parantezlerden kaçmayacak. –

3

dizeleri sadece dizeleri iseniz, bunları bir düzenli ifadeyle birleştirebiliriz, örneğin:

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

Ve sonra:

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

s !~ regexpnot s =~ regexp eşdeğer fakat okumak daha kolaydır.

Dosyayı kapatmadan File.open kullanmaktan kaçının. Dosya, atılan dosya nesnesi çöp toplanıncaya kadar açık kalacaktır; bu, programınızın dosya tanıtıcılarının tükeneceği kadar uzun olabilir. Eğer daha fazlasını yapmak gerekirse tam o satırları okuyun:

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

Yakut blok sonunda dosyayı kapatır.

Ayrıca, find_all ve pozitif bir eşlemenin kullanılmasının reddedilenden ve negatif eşleşmeden daha kolay okunıp okunamayacağını da düşünebilirsiniz. Okuyucunun aklı geçmek zorundadır az negatifler, daha net kodu:

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

+1, 'File.open' ve 'find_all 'blok formunda – pierrotlefou

10

Bob'un cevabı gibi ama sadece klavyenizdeki zaman kazanmak için:

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

Çözümünüz işe yaramaz çünkü' sync 'etrafında parantezlerden kurtulmuyor, Bob'un çözümü ise. –

+0

Sanırım soru, enterpolasyonlu düzenli ifadeleri nasıl yapacağımıza dair daha önemliydi. güncellenmiş – trevorgrayson