【问题标题】:Why do substrings prevent match with negative lookahead?为什么子字符串会阻止与负前瞻匹配?
【发布时间】:2019-08-13 22:29:33
【问题描述】:

考虑以下测试数据:

x.foo,x.bar
y.foo,y.bar
yy.foo,yy.bar

x.foo,y.bar
y.foo,x.bar
yy.foo,x.bar
x.foo,yy.bar
yy.foo,y.bar
y.foo,yy.bar

我正在尝试编写一个正则表达式,其中.foo 之前的字符串和.bar 之前的字符串彼此不同。前三项不应匹配。其他六个应该。

这主要是有效的:

^(.+?)\.foo,(?!\1)(.+?)\.bar$

但是,它错过了最后一个,因为 y 在匹配组 1 中,因此 yy 在匹配组 2 中不匹配。

互动:https://regex101.com/r/Pv5062/1

如何修改负前瞻模式以使最后一项也匹配?

【问题讨论】:

  • ^(.+?)\.foo,(?!\1\.)(.+?)\.bar$

标签: regex pcre regex-lookarounds


【解决方案1】:

内联反向引用不存储上下文信息,它们只保留捕获的文本。您需要自己指定上下文。

你可以在\1后面加一个点:

^(.+?)\.foo,(?!\1\.)(.+?)\.bar$
                 ^^ 

或者,甚至重复第二个(.+?)之后的部分:

^(.+?)\.foo,(?!\1\.bar$)(.+?)\.bar$

或者,如果bar 部分不能包含.,你可以让它更“通用”:

^(.+?)\.foo,(?!\1\.[^.]+$)(.+?)\.bar$

请参阅regex demoanother regex demo

重点是:您的(?!\1) 不是“锚定”的,如果存储在第 1 组中的文本立即出现在当前位置的右侧,则匹配失败无论上下文如何。要解决此问题,您需要提供此上下文。因为可以与.+? 匹配的值几乎可以包含任何您可以依赖的内容,即前瞻后的“硬编码”位。

【讨论】:

  • 非常有帮助。感谢您的详细解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-16
  • 2020-06-11
  • 1970-01-01
  • 1970-01-01
  • 2013-05-27
  • 2021-09-05
  • 1970-01-01
相关资源
最近更新 更多