2013-07-18 24 views
4

我見過這個問題,並回答了for javascript regex,答案很長很醜。好奇,如果任何人有一個更清晰的方式來實現紅寶石。Ruby正則表達式:獲取捕獲索引

這裏就是我想要實現:

測試字符串:"foo bar baz"
正則表達式:/.*(foo).*(bar).*/
預期收益:[[0,2],[4,6]]

所以我的目標是能夠到運行一個方法,傳遞測試字符串和正則表達式,這將返回每個捕獲組匹配的索引。我在預期回報中包括了捕獲組的起始和結束索引。我將繼續努力,並在這裏加入我自己的潛在解決方案。當然,如果除了正則表達式之外的其他方法會更清晰/更容易實現這一點,那也是一個很好的答案。

回答

5

像這樣的東西應該適用於大量的匹配。

def match_indexes(string, regex) 
    matches = string.match(regex) 

    (1...matches.length).map do |index| 
    [matches.begin(index), matches.end(index) - 1] 
    end 
end 

string = "foo bar baz" 

match_indexes(string, /.*(foo).*/) 
match_indexes(string, /.*(foo).*(bar).*/) 
match_indexes(string, /.*(foo).*(bar).*(baz).*/) 
# => [[0, 2]] 
# => [[0, 2], [4, 6]] 
# => [[0, 2], [4, 6], [8, 10]] 

你可以看看(這種奇怪的)MatchData類的工作原理。 http://www.ruby-doc.org/core-1.9.3/MatchData.html

5
m = "foo bar baz".match(/.*(foo).*(bar).*/) 
[1, 2].map{|i| [m.begin(i), m.end(i) - 1]} 
# => [[0, 2], [4, 6]] 
+2

這真棒 - 很好的答案,這麼快!唯一讓我困擾的是地圖開始處的數組,它必須手動設置以匹配捕獲組的數量。也許這樣的事情能解決這個問題? '1.upto(m.size-1).to_a.map {| I | [m.begin(i),m.end(i) - 1]}' –

+1

你可以這樣做,但你不需要'to_a'。 – sawa