【问题标题】:Negative Look Ahead负面展望
【发布时间】:2012-12-03 06:49:10
【问题描述】:

考虑两个printk 类型的函数调用 -

TRACE_BR(TRACE ,    "END. rc = %d\n", rc );

TRACE_BR(TRACE, "Value = %s", string );

我正在编写一个正则表达式来匹配上面的整个函数调用,其中在其中的字符串参数中有%,但如果字符串END也在其中,则不应匹配。

我像这样使用负前瞻

TRACE_BR\(TRACE.*?(?!END)%.*

我希望这个正则表达式只匹配第二个函数调用,但它也匹配第一个。

我想我在贪婪的* 部分出了点问题。

【问题讨论】:

  • TRACE_BR\(TRACE(?!.*END).*?%.* 我不完全确定您的要求,但我发布的正则表达式将丢弃任何出现在 TRACE 之后的带有 END 子字符串的行。
  • @nhahtdh 您的正则表达式似乎满足我的要求。但是为什么我的不工作?您可以发布您的评论作为答案并在那里添加您的详细说明。当谈到环顾四周时,我很困惑
  • 它不起作用,因为 TRACE.*?(?!END)% 消耗输入直到 %.负前瞻从 % 之前的位置开始检查,并且由于该位置没有 END,因此正则表达式匹配。这就是为什么你需要 .* 在你的否定前瞻中,并按照@PavanManjunath 的建议在其后加上外部 .* 。
  • @ZólyomiIstván 为什么会一直消耗到%,而在% 之前还有一个负前瞻?引擎不是在先行中找到字符串后立即停止吗?
  • @PavanManjunath:正则表达式引擎可能会或可能不会在 % 之前使用,但从逻辑上讲,% 充当某种“锚”,限制了字符串的可能性匹配正则表达式:对于匹配整个正则表达式的字符串,字符串必须在某个时刻包含%。在那之前,你做了一个否定断言,这是完全没有用的,因为如果下一个字符是%,它总是正确的。

标签: regex regex-lookarounds negative-lookahead


【解决方案1】:

正则表达式应该是:

TRACE_BR\(TRACE(?!.*END).*?%.*

如果END 是出现在TRACE 之后的子字符串,则此正则表达式将不匹配该行。如果您想要更精细的匹配,您可能需要修改正则表达式。

您可以将正则表达式视为:在我匹配TRACE(以及前面的等)之后,从当前位置,我想向前看,我找不到END 子字符串。

在您的正则表达式中,如果否定前瞻断言之后的字符是%,则断言始终为真,因为END 子字符串不能从那里开始;如果否定前瞻断言后的字符不是%,则正则表达式将无法匹配并回溯。

在您删除 % 的假设情况下,正则表达式仍将允许带有 END 的字符串通过,因为任何字符的序列 .*? 将允许否定前瞻匹配沿途的任何位置,它可以找到一个不是字符串END开头的位置并匹配它。

【讨论】:

    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 2018-09-06
    • 1970-01-01
    • 2016-09-07
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多