小编典典

正则表达式和否定整个字符组

all

我正在尝试一些我觉得对我来说应该相当明显的东西,但事实并非如此。我正在尝试匹配一个不包含特定字符序列的字符串。我尝试使用[^ab],[^(ab)]等来匹配不包含
‘a’s 或 ‘b’s,或仅包含 ‘a’s 或仅包含 ‘b’s 或 ‘ba’ 但不匹配 ‘ab’
的字符串。我给出的示例与“ab”不匹配,这是真的,但它们也不会单独匹配“a”,我需要它们。有一些简单的方法可以做到这一点吗?


阅读 81

收藏
2022-05-29

共1个答案

小编典典

使用负前瞻:

^(?!.*ab).*$

更新:在下面的评论中,我说这种方法比Peter’sanswer中给出的方法慢。从那以后我进行了一些测试,发现它确实稍微快了一点。然而,之所以喜欢这种技术而不是另一种技术的原因不是速度,而是简单。

使用诸如[^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).)+$

无论我是在整个文本中搜索匹配项,还是将其分成几行并单独匹配它们,锚定前瞻始终优于浮动前瞻。

2022-05-29