【问题标题】:regex: Why this negative lookahead doesn't work?正则表达式:为什么这种消极的前瞻不起作用?
【发布时间】:2016-07-25 16:36:43
【问题描述】:

我有这样的文字

real:: a
real :: b
real c

现在我想匹配那些没有:: 的实数,在这种情况下,我只想匹配第三个实数。所以我尝试了带有前瞻的正则表达式

real\s*(?!::)

但这匹配

real :: b
real c

对于\s* 表示零个或多个\s,为什么要匹配real :: b

更新

感谢 Wiktor Stribiżew。使用 regex101 调试工具。我们可以找到backtrack 让事情变得复杂。

我想出了另一个类似但我无法解决的任务

real (xx(yy)) :: a
real (zz(pp)):: b
real (cc(rr)) c

再次,我想匹配没有:: 关注的real (cc(rr))

real\s*\(.*?\)+(?!\s*::)

这是我尝试过的,但失败了。查看正则表达式调试,这也是由于回溯。但是如何正确地做到这一点呢?

【问题讨论】:

    标签: regex


    【解决方案1】:

    您需要将\s* 放入前瞻中:

    real(?!\s*::)
    

    regex demo

    real\s*(?!::) 匹配 real,因为 real 匹配 real,然后 \s* 匹配 0 个或多个空格,然后前瞻在 :: 匹配失败 并且引擎回溯,即释放与\s*匹配的空间,并尝试重新匹配字符串。由于\s* 可以匹配空字符串,所以:: b 之前的real 会匹配。

    查看regex debugger scheme at regex101 显示幕后发生的事情:

    【讨论】:

    • 好的,但你能解释一下我的正则表达式失败的原因吗?
    • 我添加了为什么超前之外的\s* 与第二种情况匹配的解释,并添加了来自 regex101 的图表来说明该过程。
    • @user15964 断言是Negative Lookahead Assertion。这意味着它断言内容不会立即出现在它放置的位置之后。
    • 是的,还请注意,如果您使用real\s+(?!::),则不会匹配第二种情况,但如果real 后跟2 个或更多空格和::,它将捕获real - 回溯的工作与上述相同。
    • 哇,其实我之前试过regex101。但是我错过了调试器工具!非常感谢您展示这个,非常有用!
    猜你喜欢
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    • 2018-06-28
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    相关资源
    最近更新 更多