带加号量词的字符范围后的负前瞻不起作用

2024-05-28 18:59:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图实现一个正则表达式,它包含所有具有任意字数但后面不能跟a:的字符串,如果后面跟a:则忽略匹配。我决定用一种消极的眼光来看待它

/([a-zA-Z]+)(?!:)/gm
string: lame:joker

因为我使用的是字符范围,所以它一次只匹配一个字符,并且只忽略以下字符之前的最后一个字符:。 在这种情况下,如何忽略整个匹配

指向regex101的链接:https://regex101.com/r/DlEmC9/1


Tags: 字符串httpsstring链接情况字符指向消极
2条回答

这个问题与回溯有关:一旦你的[a-zA-Z]+到达一个:,引擎从失败的位置后退,重新检查前瞻匹配,并在冒号前至少有两个字母时找到匹配,返回一个没有紧跟:的字母。参见your regex democ:real中的c不匹配,因为没有位置可回溯,并且real:c中的rea匹配,因为a后面没有紧跟:

将隐含需求添加到负面前瞻中

因为您只需要匹配一个不后跟冒号的字母序列,所以可以显式地添加另一个隐含的条件:且不后跟另一个字母

[A-Za-z]+(?![A-Za-z]|:)
[A-Za-z]+(?![A-Za-z:])

regex demo。因为[A-Za-z]:都匹配一个字符,所以将它们放在一个字符类中是有意义的,所以[A-Za-z]+(?![A-Za-z:])更好

通过使用单词边界防止回溯到类似单词的模式

作为@scnerd suggests,单词边界在这些情况下也会有所帮助,但总有一个问题:单词边界的含义取决于上下文(请参见word boundary explanation中的许多if

[A-Za-z]+\b(?!:)

在这里是有效的解决方案,因为输入意味着单词以非单词字符结尾(即字符串结尾,或字母、数字和下划线以外的字符)。见regex demo

单词边界何时失效

\b当主消费模式应该匹配时,即使与其他单词字符粘在一起,也不是正确的选择。最常见的例子是匹配数字:

  • \d+\b(?!:){a6}{}在{}中,但不在{}、{}和{}中
  • \d+(?![\d:]){a7}{}在{}{}和{}中,而不仅仅在{}中

+之后执行单词边界检查\b,以要求它到达单词的末尾

([a-zA-Z]+\b)(?!:)

Here's an example run

相关问题 更多 >

    热门问题