我的正则表达式如下(\d+_)*,测试字符串是1_2_3_. Ruby 正确匹配字符串。然而,匹配数据只返回“3_”作为匹配。
例如
irb(main):004:0> /(\d+_)*/.match("1_2_3_")
=> #<MatchData "1_2_3_" 1:"3_">
Run Code Online (Sandbox Code Playgroud)
我希望像 #<MatchData "1_2_3_" 1:"1_", 2:"2_", 3:"3_">
该组的每次新重复都会覆盖之前的匹配。所有正则表达式引擎都以这种方式工作。据我所知,只有 .NET 正则表达式引擎提供了一种访问重复组的所有匹配项(所谓的“捕获”)的方法。
想象一下发生了什么。在正则表达式中,每对括号构建一个捕获组;它们从左到右编号。所以在/(\d+_)*/,(\d+_)正在捕获组号 1。
现在,如果您将该正则表达式应用于1_2_,会发生什么?
(\d+_) 火柴 1_1_存储为第一个捕获组的内容。您现在可以访问\1以查看这些内容。*告诉正则表达式引擎重试从当前位置匹配。(\d+_) 现在匹配 2_2_再次需要存储在组号 1/backreference 中\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_"]
Run Code Online (Sandbox Code Playgroud)