此问题已在此处有答案:
Regular expression to match a line that doesn't contain a word(34答案)
六年前就关门了。
我正在尝试一些我觉得对我来说应该是相当明显的事情,但事实并非如此。我试图匹配一个不包含特定字符序列的字符串。我试过使用[^ab]
,[^(ab)]
等。匹配不包含“a”或“B”的字符串,或者只包含“a”或"B“或”ba“但不匹配”ab“的字符串。我给出的例子不会匹配'ab',这是真的,但它们也不会单独匹配'a',我需要它们。有没有简单的方法可以做到这一点?
9条答案
按热度按时间nwo49xxi1#
使用字符类(如
[^ab]
)将匹配不在字符集内的单个字符。(其中^
是否定部分)。要匹配不包含多字符序列
ab
的字符串,您需要使用负向前查找:上面的表达式在正则表达式注解模式下分解为:
nom7f22z2#
使用负前瞻(参见Regexr.com explanation):
更新:在下面的评论中,我指出这种方法比Peter's answer中给出的方法慢。从那以后,我做了一些测试,发现它真的稍微快一点。然而,这种技术优于其他技术的原因不是速度,而是简单性。
另一种技术,在这里被描述为 tempered greedy token,适用于更复杂的问题,例如匹配分隔符由多个字符组成的分隔文本(如HTML,如Luke在下面评论的)。对于问题中描述的问题,这是矫枉过正。
对于任何感兴趣的人,我用一大块Lorem Ipsum文本进行了测试,计算了不包含单词“quo”的行数。以下是我使用的正则表达式:
无论我是在整个文本中搜索匹配,还是将其分解为行并单独匹配,锚定的前瞻始终优于浮动的前瞻。
dy1byipe3#
这就是所谓的消极前瞻。它是这样的-
(?!regex here)
。所以abc(?!def)
将匹配abcnot后跟def。所以它会匹配abc,abc,abc,等等。类似地,存在正向前看-
(?=regex here)
。所以abc(?=def)
将匹配abc后面跟着def。还有负向后看和正向后看-分别为
(?<!regex here)
和(?<=regex here)
需要注意的一点是,负前瞻是零宽度的。也就是说,它不算占用了任何空间。
因此,它看起来像
a(?=b)c
将匹配“abc”,但它不会。它将匹配'a',然后是'B'的正向前看,但它不会向前移动到字符串中。然后,它将尝试将“c”与“B”匹配,但这不起作用。类似地,^a(?=b)b$
将匹配'ab'而不是'abb',因为查找范围是零宽度的(在大多数正则表达式实现中)。有关this页面的更多信息
bbuxkriu4#
abc(?!def)将匹配abc而不是def。所以它会匹配abc,abc,abc,等等。如果我既不想要def也不想要xyz,它会是abc吗?!(def)(xyz))???
我也有同样的问题,并找到了解决办法:
这些不计数的组由“AND”组合,所以这应该可以做到这一点。希望有帮助。
vdzxcuhz5#
使用你描述的正则表达式是一种简单的方法(据我所知)。如果你想要一个范围,你可以使用[^a-f]。
ctehm74n6#
最简单的方法是完全从正则表达式中提取否定:
u0njafvf7#
只需在字符串中搜索“ab”,然后对结果求反:
这似乎更容易,也应该更快。
mw3dktmi8#
在这种情况下,我可能只是简单地避免正则表达式,并使用如下内容:
这可能也会快得多(上面对regex的快速测试显示,该方法占用的时间约为regex方法的25%)。一般来说,如果我知道要查找的字符串,我会发现正则表达式是多余的。因为你知道你不想要“ab”,所以测试字符串是否包含该字符串是一件简单的事情,而不需要使用正则表达式。
8hhllhi29#
例如,正则表达式[^ab]将匹配'ab ab ab',但不匹配'ab',因为它将匹配字符串' a'或'b '。
你有什么语言/场景?你能从原始集合中减去结果,然后只匹配ab吗?
如果您使用GNU grep,并且正在解析输入,请使用'-v'标志来反转结果,返回所有不匹配的结果。其他正则表达式工具也有一个“返回非匹配”函数。
如果我理解正确的话,你想要所有的东西,除了那些在任何地方都包含“ab”的项目。