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

Kri*_*rma 11 ruby regex position pattern-matching

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
Run Code Online (Sandbox Code Playgroud)

这只匹配它看起来的第一次出现.
string.scan部分工作,但它没有告诉匹配模式的索引.

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

Nak*_*lon 20

你可以使用.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
Run Code Online (Sandbox Code Playgroud)

输出:

[0, "Jack"]
[9, "Jill"]
[57, "Jack"]
[97, "Jill"]
Run Code Online (Sandbox Code Playgroud)

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"]]
Run Code Online (Sandbox Code Playgroud)