在带有加号量词的字符范围后负先行不起作用
Negative lookahead not working after character range with plus quantifier
我正在尝试实现一个正则表达式,其中包括所有具有任意数量的单词但不能后跟 : 的字符串,如果匹配则忽略。我决定用消极的眼光看待它。
/([a-zA-Z]+)(?!:)/gm
string: lame:joker
因为我使用的是一个字符范围,它一次匹配一个字符并且只忽略 : 之前的最后一个字符。
在这种情况下如何忽略整个匹配?
Link 到 regex101:https://regex101.com/r/DlEmC9/1
在 +
之后进行单词边界检查 \b
以要求它到达单词的末尾。
([a-zA-Z]+\b)(?!:)
此问题与 回溯 相关:一旦您的 [a-zA-Z]+
到达 :
,引擎就会从失败的位置后退,重新检查前瞻匹配并在冒号前至少有两个字母时找到一个匹配项,返回没有紧跟 :
的那个。参见your regex demo:c:real
中的c
没有匹配到,因为没有回溯到的位置,real:c
中的rea
匹配到,因为a
没有紧跟 :
.
向否定先行添加隐式要求
由于您只需要匹配不带冒号的字母序列,您可以显式添加一个隐含的条件:且不带另一个字母[=73=]:
[A-Za-z]+(?![A-Za-z]|:)
[A-Za-z]+(?![A-Za-z:])
见regex demo。由于[A-Za-z]
和:
都匹配一个字符,所以将它们放在一个字符class中是有意义的,所以,[A-Za-z]+(?![A-Za-z:])
更好。
使用单词边界防止回溯到类似单词的模式
如, word boundaries can also help in these situations, but there is always a catch: word boundary meaning is context dependent (see a number of ifs in the word boundary explanation).
[A-Za-z]+\b(?!:)
在这里是一个有效的解决方案,因为输入意味着单词以非单词字符结尾(即字符串结尾,或字母、数字和下划线以外的字符)。见 regex demo.
什么时候单词边界失效?
\b
当主要消费模式应该匹配时,即使粘附到其他单词字符,也不会是正确的选择。最常见的例子是匹配数字:
我正在尝试实现一个正则表达式,其中包括所有具有任意数量的单词但不能后跟 : 的字符串,如果匹配则忽略。我决定用消极的眼光看待它。
/([a-zA-Z]+)(?!:)/gm
string: lame:joker
因为我使用的是一个字符范围,它一次匹配一个字符并且只忽略 : 之前的最后一个字符。 在这种情况下如何忽略整个匹配?
Link 到 regex101:https://regex101.com/r/DlEmC9/1
在 +
之后进行单词边界检查 \b
以要求它到达单词的末尾。
([a-zA-Z]+\b)(?!:)
此问题与 回溯 相关:一旦您的 [a-zA-Z]+
到达 :
,引擎就会从失败的位置后退,重新检查前瞻匹配并在冒号前至少有两个字母时找到一个匹配项,返回没有紧跟 :
的那个。参见your regex demo:c:real
中的c
没有匹配到,因为没有回溯到的位置,real:c
中的rea
匹配到,因为a
没有紧跟 :
.
向否定先行添加隐式要求
由于您只需要匹配不带冒号的字母序列,您可以显式添加一个隐含的条件:且不带另一个字母[=73=]:
[A-Za-z]+(?![A-Za-z]|:)
[A-Za-z]+(?![A-Za-z:])
见regex demo。由于[A-Za-z]
和:
都匹配一个字符,所以将它们放在一个字符class中是有意义的,所以,[A-Za-z]+(?![A-Za-z:])
更好。
使用单词边界防止回溯到类似单词的模式
如
[A-Za-z]+\b(?!:)
在这里是一个有效的解决方案,因为输入意味着单词以非单词字符结尾(即字符串结尾,或字母、数字和下划线以外的字符)。见 regex demo.
什么时候单词边界失效?
\b
当主要消费模式应该匹配时,即使粘附到其他单词字符,也不会是正确的选择。最常见的例子是匹配数字: