2024-05-28 18:59:09 发布
网友
我试图实现一个正则表达式,它包含所有具有任意字数但后面不能跟a:的字符串,如果后面跟a:则忽略匹配。我决定用一种消极的眼光来看待它
/([a-zA-Z]+)(?!:)/gm string: lame:joker
因为我使用的是字符范围,所以它一次只匹配一个字符,并且只忽略以下字符之前的最后一个字符:。 在这种情况下,如何忽略整个匹配
指向regex101的链接:https://regex101.com/r/DlEmC9/1
这个问题与回溯有关:一旦你的[a-zA-Z]+到达一个:,引擎从失败的位置后退,重新检查前瞻匹配,并在冒号前至少有两个字母时找到匹配,返回一个没有紧跟:的字母。参见your regex demo:c:real中的c不匹配,因为没有位置可回溯,并且real:c中的rea匹配,因为a后面没有紧跟:
[a-zA-Z]+
:
c: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:])更好
[A-Za-z]
[A-Za-z]+(?![A-Za-z:])
通过使用单词边界防止回溯到类似单词的模式
作为@scnerd suggests,单词边界在这些情况下也会有所帮助,但总有一个问题:单词边界的含义取决于上下文(请参见word boundary explanation中的许多if)
[A-Za-z]+\b(?!:)
在这里是有效的解决方案,因为输入意味着单词以非单词字符结尾(即字符串结尾,或字母、数字和下划线以外的字符)。见regex demo
单词边界何时失效
\b当主消费模式应该匹配时,即使与其他单词字符粘在一起,也不是正确的选择。最常见的例子是匹配数字:
\b
\d+\b(?!:)
\d+(?![\d:])
在+之后执行单词边界检查\b,以要求它到达单词的末尾
+
([a-zA-Z]+\b)(?!:)
Here's an example run
这个问题与回溯有关:一旦你的
[a-zA-Z]+
到达一个:
,引擎从失败的位置后退,重新检查前瞻匹配,并在冒号前至少有两个字母时找到匹配,返回一个没有紧跟:
的字母。参见your regex demo:c:real
中的c
不匹配,因为没有位置可回溯,并且real:c
中的rea
匹配,因为a
后面没有紧跟:
将隐含需求添加到负面前瞻中
因为您只需要匹配一个不后跟冒号的字母序列,所以可以显式地添加另一个隐含的条件:且不后跟另一个字母:
见regex demo。因为
[A-Za-z]
和:
都匹配一个字符,所以将它们放在一个字符类中是有意义的,所以[A-Za-z]+(?![A-Za-z:])
更好通过使用单词边界防止回溯到类似单词的模式
作为@scnerd suggests,单词边界在这些情况下也会有所帮助,但总有一个问题:单词边界的含义取决于上下文(请参见word boundary explanation中的许多if)
在这里是有效的解决方案,因为输入意味着单词以非单词字符结尾(即字符串结尾,或字母、数字和下划线以外的字符)。见regex demo
单词边界何时失效
\b
当主消费模式应该匹配时,即使与其他单词字符粘在一起,也不是正确的选择。最常见的例子是匹配数字:\d+\b(?!:)
{a6}{\d+(?![\d:])
{a7}{在
+
之后执行单词边界检查\b
,以要求它到达单词的末尾Here's an example run
相关问题 更多 >
编程相关推荐