2011-03-09 29 views
23

Bir normal ifadeyi eşleştirmek veruby regex: maç ve almak pozisyon (lar)

dizesinin içindeki konumu almak istiyorum Örneğin,

"AustinTexasDallasTexas".match_with_posn /(Texas)/ 

match_with_posn gibi bir şey döndürmek istiyorum: [6, 17] 6 ve 17 burada Texas kelimesinin her iki örneği için başlangıç ​​pozisyonları.

Bunun gibi bir şey var mı?

+0

olası yinelenen [Tüm olaylardan endeksleri nasıl alınır bir dizgede bir desenin] (http://stackoverflow.com/questions/4274388/how-to-get-indexes-of-all-occurrences-of-a-pattern-in-a-string) – Nakilon

cevap

43

, bunu yapabilirsiniz:

require 'enumerator' #Only for 1.8.6, newer versions should not need this. 

s = "AustinTexasDallasTexas" 
positions = s.enum_for(:scan, /Texas/).map { Regexp.last_match.begin(0) } 

Bu içeren bir dizi oluşturur:

=> [6, 17] 
ait
+0

Eğer Isateateatest atea bulmak istiyorsanız [2], ama 5 de – adcosta

+2

bir olasılık olduğunu Endeks 5'te "a" endeksi 2 bulunan "atea" eşleştirmek için kullanılır 2. "Ate" için arama bir dizi [2, 5, 8] alacaksınız. Eğer örtüşen eşleşmeleri bulmak istiyorsanız, o zaman bir lookahead iddiası kullanın: '/ (? = (Atea)) /'. 'pozisyonlar = s.enum_for (: tarama, /(?==atea))/).map {Regexp.last_match.begin (0)} # => [2, 5]' –

+0

Aşağı oy veren kişi bunu yapabilir mi? aşağı oyu açıkla? –

24

Sıralama, Şimdi String#index

"AustinTexasDallasTexas".index /Texas/ 
=> 6 

görüyorsun, dize API genişletmek olabilir. Yakut 1.8.6+ kullanma

class String 
    def indices e 
    start, result = -1, [] 
    result << start while start = (self.index e, start + 1) 
    result 
    end 
end 
p "AustinTexasDallasTexas".indices /Texas/ 
=> [6, 17] 
+0

çekicilik! Güzel! – Tilo