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(从
this answer偷来):
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,"ab"]] irb> "ab".to_enum(:scan,/(?<=a)b/).map{ |m,m] } => [[1,1,"b"]]