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

问题描述 投票:0回答:2
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
完成了部分工作,但它没有告诉任何有关匹配模式的索引的信息。

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

regex ruby position
2个回答
21
投票

你可以使用

.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"]

更新:

注意 Lookbehind 的行为 – 您将获得真正匹配部分的索引,而不是 look 的索引:

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"]]

2
投票

如果您只想将“Jack”的位置放入数组中,这里是对 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
© www.soinside.com 2019 - 2024. All rights reserved.