我正在尝试一些我觉得对我来说应该相当明显的东西,但事实并非如此。我正在尝试匹配一个不包含特定字符序列的字符串。我尝试使用[^ab],[^(ab)]等来匹配不包含 ‘a’s 或 ‘b’s,或仅包含 ‘a’s 或仅包含 ‘b’s 或 ‘ba’ 但不匹配 ‘ab’ 的字符串。我给出的示例与“ab”不匹配,这是真的,但它们也不会单独匹配“a”,我需要它们。有一些简单的方法可以做到这一点吗?
[^ab]
[^(ab)]
使用负前瞻:
^(?!.*ab).*$
更新:在下面的评论中,我说这种方法比Peter’sanswer中给出的方法慢。从那以后我进行了一些测试,发现它确实稍微快了一点。然而,之所以喜欢这种技术而不是另一种技术的原因不是速度,而是简单。
使用诸如[^ab]将匹配不在字符集中的单个字符的字符类。(^作为否定部分)。
^
要匹配不包含多字符序列的字符串ab,您需要使用负前瞻:
ab
^(?:(?!ab).)+$
在正则表达式注释模式下剖析的上述表达式是:
(?x) # enable regex comment mode ^ # match start of line/string (?: # begin non-capturing group (?! # begin negative lookahead ab # literal text sequence ab ) # end negative lookahead . # any single character ) # end non-capturing group + # repeat previous match one or more times $ # match end of line/string
另一种技术,在此描述为 缓和的贪婪令牌 ,适用于更复杂的问题,例如匹配分隔符由多个字符组成的分隔文本(如 HTML,正如 Luke 在下面评论的那样)。对于问题中描述的问题,这是矫枉过正的。
对于任何感兴趣的人,我使用大量 Lorem Ipsum 文本进行了测试,计算了不包含“quo”一词的行数。这些是我使用的正则表达式:
(?m)^(?!.*\bquo\b).+$ (?m)^(?:(?!\bquo\b).)+$
无论我是在整个文本中搜索匹配项,还是将其分成几行并单独匹配它们,锚定前瞻始终优于浮动前瞻。