如何获取字符串中所有模式的索引

string = "Jack and Jill went up the hill to fetch a pail of water. Jack fell down and broke his crown. And Jill came tumbling after. " d = string.match(/(jack|jill)/i) # -> MatchData "Jill" 1:"Jill" d.size # -> 1 

这只匹配它看起来的第一次出现。
string.scan部分完成了这项工作,但它没有说明匹配模式的索引。

如何获得模式的所有匹配实例及其索引(位置)的列表?

你可以使用.scan$`全局变量,这意味着最后一次成功匹配左边的字符串 ,但它在通常的.scan ,所以你需要这个hack (从这个答案中偷来的):

 string = "Jack and Jill went up the hill to fetch a pail of water. Jack fell down and broke his crown. And Jill came tumbling after. " string.to_enum(:scan, /(jack|jill)/i).map do |m,| p [$`.size, m] end 

输出:

 [0, "Jack"] [9, "Jill"] [57, "Jack"] [97, "Jill"] 

UPD:

注意lookbehind的行为 – 你得到真正匹配的部分的索引,而不是看起来的部分:

 irb> "ab".to_enum(:scan, /ab/ ).map{ |m,| [$`.size, $~.begin(0), m] } => [[0, 0, "ab"]] irb> "ab".to_enum(:scan, /(?<=a)b/).map{ |m,| [$`.size, $~.begin(0), m] } => [[1, 1, "b"]] 

如果你想把“杰克”的位置放到一个数组中,这里是对Nakilon答案的修改

 location_array = Array.new string = "Jack and Jack went up the hill to fetch a pail of Jack..." string.to_enum(:scan,/(jack)/i).map do |m,| location_array.push [$`.size] end