当前位置: 首页 > 知识库问答 >
问题:

正则表达式负前瞻被忽略了

云远
2023-03-14

我有以下示例文本

[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)被忽略了,因此正则表达式与整个字符串匹配。

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

Item 1
Item 3

这是有道理的,所以我真的很困惑为什么消极的前瞻性没有正常运作。

共有3个答案

楚知
2023-03-14

这里的问题是。*在负前瞻之前是贪婪的,并且会继续查找任何东西然后停止。

管理这种情况的一个方法是将这种贪婪的行为包含在像黑尔这样的消极前瞻中

https://regex101.com/r/yzUQoP/1

/\[(.*)\](?!.*注释\.md)/gm

祁均
2023-03-14

简而言之,你有太多的.*(可能导致灾难性的回溯,查一下!请记住,它们匹配任何字符零次或多次。这意味着他们会继续努力匹配,直到他们获得成功。这不一定是你想要的字符数。

解决问题的一种方法是将消极的展望向前移动到前面,如下所示:

(?!.*notes\.md)\[([^\]]+)\].*

解释

<代码>(?!.*注释\。md)对后面跟有“notes.md”的任何数量的任何字符进行否定的前瞻

\[ a [ 字符

([^\]] )组1,任何不是]的字符,一次或多次

\]a ] 字符

<代码>* 行的其余部分

使用“多行”标志获取每一

董砚
2023-03-14

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

  • \[(.*)\]匹配[项目1]
  • <代码>*匹配(./path/notes.md
  • 剩下的字符串现在是
  • (?!notes\.md)检查剩余字符串是否与模式notes\.md匹配。但事实并非如此,因此比赛仍在继续
  • \)匹配>,匹配成功

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

  • \[(.*)\]匹配[项目1]
  • 剩下的字符串现在是(./path/notes.md)
  • (?!.*Notes\. md)检查剩余字符串是否与模式匹配。*Notes\. md,它会这样做,因此匹配失败(更准确地说,正则表达式引擎会在放弃匹配之前尝试回溯,但没有替代方法来匹配\[(.*)\]',因此匹配仍然失败)。

因此,通过这一更改,它将拒绝< code>notes.md出现在< code>)之前任何位置的所有字符串。如果希望它只拒绝< code>notes.md直接出现在< code>)之前的实例,可以使用loookbehind(不带< code >)。*),或者将< code>\)添加到前瞻中。

 类似资料:
  • 问题内容: 我正在尝试对Elasticsearch查询进行否定前瞻,正则表达式为: 我要匹配的文本是: 归还了住宿费用,但仍存在建筑问题。喷洒化学药品会引起健康问题,并引起眼睛刺激。 我没有任何幸运。有人可以帮忙吗? ES查询: 问题答案: 您可以使用以下两种方法之一来解决此问题: 要么 带可选的(因为 默认情况下 为ON ) 它是如何工作的? 在常见的NFA正则表达式中,通常会有负面的环顾四周,

  • 我目前正在玩正则表达式,试图更好地理解它们,并且有一个我现在似乎正在努力的场景,因为我不知道这是否可以通过正则表达式来实现。 我有这样的文本字符串 该清单可能仍在进行中。我想匹配(选择)内部关键字之间的空格。因此,在第二行中,它将是和之间的空格。 和我能够匹配关键字中包含多个单词的行。将第一部分<代码>( 编辑:假设这些行之间还有一些其他文本,所以简单的< code>\b不能作为正则表达式使用。

  • 我试图捕捉两个最接近的短语之间的文本,包括这些短语,但消极的展望似乎在我的情况下不起作用。 因此,这是文本文件的一部分: 我需要捕捉每一对<代码> 我的正则表达式是:

  • 我想要一个 Java 正则表达式字符串,它可以在字符串中找到所有元音,除非它们: 是第一个字符或 下划线后面的下一个字符 AREA_ID变为AR_ID LONG_NAME变成 LNG_NM 孤独的家变成了ALN 我曾经使用过http://gskinner.com/RegExr,现在我有了下面的正则表达式来替换所有元音字母,除非它是起始字符 我想不出第二部分怎么弄(忽略紧跟在下划线后面的元音)。

  • 我有一个用于匹配 URL 的正则表达式(它完成了工作,它为我想要的而工作。但是,当我不希望它时,它也会匹配电子邮件的域。 当前匹配项: < li>http://www.foo.bar < li>foo.bar < li >网址:foo.bar(与foo.bar部分匹配) < li>info@foo.bar(匹配foo.bar部分) 我不希望它匹配最后一个,所以它只匹配前三个。我尝试添加到前面,但这

  • 我定义的正则表达式对所有测试字符串都很好,除了当捕获组顺序被交换时(2016 Fall或16F或18SU),正则表达式中是否有一种方法可以忽略正则表达式的捕获组顺序