shy*_*dia 4 python regex regex-lookarounds
我正在尝试实现一个正则表达式,其中包含所有具有任意数量单词但不能后跟 : 的字符串,如果匹配则忽略匹配项。我决定对它进行负面展望。
/([a-zA-Z]+)(?!:)/gm
string: lame:joker
Run Code Online (Sandbox Code Playgroud)
因为我使用的是一个字符范围,它一次匹配一个字符,并且只忽略 : 之前的最后一个字符。在这种情况下,我如何忽略整个比赛?
regex101 链接:https ://regex101.com/r/DlEmC9/1
该问题与回溯有关:一旦[a-zA-Z]+到达 a :,引擎就会从失败位置后退,重新检查前向匹配,并在冒号之前至少有两个字母时找到匹配项,返回不是立即出现的字母其次是:。请参阅您的正则表达式演示:cinc:real不匹配,因为没有位置可回溯,而reainreal:c匹配,因为a后面没有紧跟:。
向否定前瞻添加隐式要求
由于您只需要匹配后面不跟冒号的字母序列,因此您可以显式添加一个隐含的条件:并且后面不跟另一个字母:
[A-Za-z]+(?![A-Za-z]|:)
[A-Za-z]+(?![A-Za-z:])
Run Code Online (Sandbox Code Playgroud)
请参阅正则表达式演示。由于 和 都[A-Za-z]匹配:单个字符,因此将它们放入单个字符类是有意义的,因此[A-Za-z]+(?![A-Za-z:])更好。
使用单词边界防止回溯到类似单词的模式
正如@scnerd 所建议的,单词边界在这些情况下也能有所帮助,但总是有一个问题:单词边界的含义是依赖于上下文的(请参阅单词边界解释中的许多if)。
[A-Za-z]+\b(?!:)
Run Code Online (Sandbox Code Playgroud)
在这里是一个有效的解决方案,因为输入意味着单词以非单词字符结尾(即字符串结尾,或字母、数字和下划线以外的字符)。请参阅正则表达式演示。
字边界什么时候会失效?
\b当主要消费模式应该匹配时,即使粘到其他单词字符上,也不是正确的选择。最常见的例子是匹配数字: