正则表达式负先行被忽略

标签 regex regex-lookarounds regex-group

我有以下示例文本

[Item 1](./path/notes.md)
[Item 2](./path)
[Item 3](./path/notes.md)
[Item 4](./path)

当我应用以下正则表达式 \[(.*)\].*(?!notes\.md).*\) 时,我希望在打印第一个捕获时得到以下输出组

Item 2
Item 4

但我最终得到的是

Item 1
Item 2
Item 3
Item 4

在我看来,负前瞻部分 (?!notes\.md) 由于某种原因被忽略了,所以正则表达式匹配了整个字符串。

真正让我困惑的是,积极的前瞻性工作如我所料。例如,使用 \[(.*)\].*(?=notes\.md).*\) 在打印第一个捕获组时返回以下内容

Item 1
Item 3

这是有道理的,所以我真的很困惑为什么负先行不能正常工作。

最佳答案

让我们来看看在第 1 项上匹配您的模式时会发生什么:

  • \[(.*)\] 匹配 [Item 1]
  • .* 匹配 (./path/notes.md
  • 剩下的字符串现在是 )
  • (?!notes\.md) 检查剩余字符串是否与模式 notes\.md 匹配。它没有,所以比赛继续。
  • \)匹配),匹配成功。

如果您更改它,使前瞻之前的 .* 位于前瞻内部 (\[(.*)\](?!.*notes\.md)。 *\)),它现在将按如下方式工作:

  • \[(.*)\] 匹配 [Item 1]
  • 剩下的字符串现在是 (./path/notes.md)
  • (?!.*notes\.md) 检查剩余字符串是否与模式 .*notes\.md 匹配,匹配失败(更准确地说,正则表达式引擎会在放弃匹配之前尝试回溯,但没有其他方法可以匹配 \[(.*)\]',所以匹配仍然失败) .

因此,随着该更改,它将拒绝 notes.md 出现在 ) 之前的所有字符串。如果您希望它只拒绝 notes.md 直接出现在 ) 之前的实例,您可以使用 loookbehind(没有 .*)或将 \) 添加到 lookahead。

关于正则表达式负先行被忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66947059/

相关文章:

javascript - 当找到匹配项时,javascript exec 不会停止吗?

python - Python Django RegExp错误

python - "select filenames whithout extansion"的负前瞻

regex - 使用 vim 正则表达式对数字进行通信

regex - 乐正则表达式 : How to use capturing group inside lookaheads

javascript - 如何从正则表达式匹配函数中获取匹配的组?

regex - 从 img 标签中提取 src 属性的正则表达式

java - 如何在java中只找到精确的模式匹配?

python - 用于识别组的正则表达式

c# - 具有最大长度的 float 的正则表达式