我正在尝试一些我认为应该对我来说相当明显的东西,但事实并非如此。我正在尝试匹配一个不包含特定字符序列的字符串。我已尝试使用[^ab]
,[^(ab)]
等匹配不包含'a'或'b'的字符串,或仅包含'a'或仅'b'或'ba'但不匹配'ab'的字符串。我给出的例子不符合'ab'这是真的,但它们也不会单独匹配'a'而我需要它们。有一些简单的方法可以做到吗?
答案 0 :(得分:311)
使用[^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
答案 1 :(得分:168)
使用否定前瞻:
^(?!.*ab).*$
更新:在下面的评论中,我说这种方法比Peter's answer中给出的方法慢。从那时起我就进行了一些测试,结果发现它确实稍微快一些。然而,偏爱另一种技术的原因不是速度,而是简单性。
另一种技术,将here描述为淬火贪婪令牌,适用于更复杂的问题,例如匹配分隔符文本,其中分隔符由多个字符组成(如HTML,如Luke评论below)。对于问题中描述的问题,这太过分了。
对于任何感兴趣的人,我使用大量的Lorem Ipsum文本进行测试,计算不包含“quo”一词的行数。这些是我使用的正则表达式:
(?m)^(?!.*\bquo\b).+$
(?m)^(?:(?!\bquo\b).)+$
无论是在整个文本中搜索匹配,还是将其分解为行并单独匹配,锚定前瞻一直优于浮动前瞻。
答案 2 :(得分:51)
是的,它被称为负向前瞻。它是这样的 - (?!regex here)
。因此abc(?!def)
将匹配abc 而不是,然后是def。所以它会匹配abce,abc,abck等。
同样有积极的前瞻 - (?=regex here)
。因此abc(?=def)
将匹配abc,然后是def。
还有负面和正面的后视 - 分别为(?<!regex here)
和(?<=regex here)
需要注意的一点是负前瞻是零宽度。也就是说,它不算是占用了任何空间。
所以看起来a(?=b)c
可能会匹配“abc”,但事实并非如此。它将匹配'a',然后是'b'的正向前瞻,但它不会向前移动到字符串中。然后它会尝试将'c'与'b'匹配,这将无效。类似地,^a(?=b)b$
将匹配'ab'而不是'abb',因为外观是零宽度(在大多数正则表达式实现中)。
有关this页
的更多信息答案 3 :(得分:6)
正如您所描述的那样使用正则表达式是一种简单的方法(据我所知)。如果你想要一个范围,你可以使用[^ a-f]。
答案 4 :(得分:5)
最简单的方法是完全从正则表达式中取消否定:
if (!userName.matches("^([Ss]ys)?admin$")) { ... }
答案 5 :(得分:5)
abc(?!def)将匹配abc未遵循 通过def。所以它会匹配abce,abc, abck,等等,如果我不想要def 也不是xyz会是abc(?!(def)(xyz)) ???
我有同样的问题并找到了解决方案:
abc(?:(?!def))(?:(?!xyz))
这些非计数组由“AND”组合,所以这应该可以解决问题。希望它有所帮助。
答案 6 :(得分:4)
正则表达式[^(ab)]将匹配例如'ab ab ab ab'但不匹配'ab',因为它将匹配字符串'a'或'b'。
你有什么语言/场景?你能从原始集中减去结果,只匹配ab?
如果您正在使用GNU grep,并且正在解析输入,请使用'-v'标志反转您的结果,返回所有不匹配。其他正则表达式工具也具有“返回非匹配”功能。
如果我理解正确,除了那些在任何地方都包含'ab'的项目之外你想要的一切。
答案 7 :(得分:4)
只需在字符串中搜索“ab”,然后否定结果:
!/ab/.test("bamboo"); // true
!/ab/.test("baobab"); // false
看起来更容易,也应该更快。
答案 8 :(得分:3)
在这种情况下,我可能只是完全避免使用正则表达式,并使用类似的内容:
if (StringToTest.IndexOf("ab") < 0)
//do stuff
这可能也会快得多(快速测试与上面的正则表达式相比,这种方法占据了正则表达式方法的大约25%的时间)。一般来说,如果我知道我正在寻找的确切字符串,我发现正则表达式是过度的。既然你知道你不想要“ab”,那么测试字符串是否包含该字符串是一件简单的事情,而不使用正则表达式。