我的正则表达式是以下(\d+_)*
,测试字符串是1_2_3_
。 Ruby正确匹配字符串。但是,matchdata仅返回“3_”作为匹配。
e.g。
irb(main):004:0> /(\d+_)*/.match("1_2_3_")
=> #<MatchData "1_2_3_" 1:"3_">
我期待#<MatchData "1_2_3_" 1:"1_", 2:"2_", 3:"3_">
答案 0 :(得分:4)
该组的每次重复都会覆盖上一场比赛。所有正则表达式引擎都以这种方式工作。据我所知,只有.NET正则表达式引擎提供了一种访问重复组的所有匹配的方法(所谓的“捕获”)。
想象一下发生了什么。在正则表达式中,每对括号都构建一个捕获组;它们从左到右编号。因此,在/(\d+_)*/
中,(\d+_)
正在捕获第1组。
现在,如果您将该正则表达式应用于1_2_
,会发生什么?
(\d+_)
匹配1_
1_
被存储为第一个捕获组的内容。您现在可以访问\1
以查看这些内容。*
告诉正则表达式引擎从当前位置重试匹配。(\d+_)
现在匹配2_
2_
再次需要存储在第1组/反向引用\1
中。所以它会覆盖那里的任何内容。要在Ruby中获得所需的结果,您需要进行两次正则表达式匹配:/(?:\d+_)*/
用于整体匹配,/\d+_/
用于每次匹配:
irb(main):001:0> s = "1_2_3_"
=> "1_2_3_"
irb(main):009:0> s.match(/(?:\d+_)*/)
=> #<MatchData "1_2_3_">
irb(main):007:0> s.scan(/\d+_/)
=> ["1_", "2_", "3_"]
答案 1 :(得分:0)
我相信你想要.scan
。它将返回一系列匹配。
答案 2 :(得分:0)
"1_2_3_".scan(/\d+_/) # => ["1_", "2_", "3_"]
将为您提供所需的信息。 (注意删除*
)。我还删除了分组b / c,它只是产生一个数组数组,即[["1_"], ["2_"], ["3_"]]