正向回顾和重复模式存在问题

3
考虑以下字符串:
ab(cd.xz) e(ab(fg).xz)) ab(hi.xz)

我希望能够匹配以ab(开始并以z结尾的所有子字符串。因此,我编写了以下正则表达式:

(?<=a.*?\().*?z

根据RegexBuddy的提示,这应该尝试执行以下操作:

Assert that the regex below can be matched, with the match ending at this position (positive lookbehind) «(?<=a.*?\()»
   Match the character “a” literally «a»
   Match any single character that is not a line break character «.*?»
      Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
   Match the character “(” literally «\(»
Match any single character that is not a line break character «.*?»
   Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
Match the character “z” literally «z»

我在RegexBuddy中得到的结果如下(请注意中间的一个匹配不正确,应该匹配fg).xz)。我做错了什么?

2个回答

4
正则表达式按设计工作 :)
在第二个例子中,回顾表达式匹配ab(cd.xz) e(。回顾匹配总是从字符串开头开始尝试(必要时向前移动),因此.*?匹配的内容比你想象的要多。它实际上并不像人们期望的那样从当前位置向后执行。
所以在第三个例子中,回顾甚至匹配ab(cd.xz) e(ab(fg).xz)) ab(。它之所以似乎能正确工作,只是因为实际匹配始于另一个ab(...
解决方案:更明确地规定允许匹配的内容。我建议将括号从允许匹配的字符中删除:
(?<=a[^()]*\().*?z

+1 不仅你的例子可行,而且你还解释了我的错误。非常感谢你。 - Matt

0

根据您的要求"从ab(开始,以z结尾",则表达式应为:

(?<=ab\().*?z

如果您需要匹配并仅捕获*z,则此表达式可用:a*(*z
(?<=a[^(]*\().*?z

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接