正则表达式和对整个字符组求反

我在尝试一些我觉得对我来说应该相当明显的事情,但事实并非如此。我试图匹配一个不包含特定字符序列的字符串。我已经尝试使用[^ab][^(ab)]等来匹配不包含'a'或'b'的字符串,或只包含'a'或'b'或'ba',但不匹配'ab'。我给出的例子不能匹配ab,这是真的,但它们也不能单独匹配a,我需要它们。有什么简单的方法吗?

328522 次浏览

使用你所描述的正则表达式是最简单的方法(据我所知)。如果你想要一个范围,你可以使用[^a-f]。

使用消极前视:

^(?!.*ab).*$

更新:在下面的评论中,我说过这种方法比彼得的回答中给出的方法慢。从那以后,我进行了一些测试,发现它确实快了一些。然而,与其他技术相比,更喜欢这种技术的原因不是速度,而是简单。

另一种技术,将在这里描述为缓和贪婪令牌,适用于更复杂的问题,如匹配分隔符由多个字符组成的分隔文本(如HTML,如Luke注释的下面)。对于问题中描述的问题,它是多余的。

对于任何感兴趣的人,我用Lorem Ipsum的大量文本进行了测试,计算了不包含“quo”一词的行数。这些是我使用的正则表达式:

(?m)^(?!.*\bquo\b).+$


(?m)^(?:(?!\bquo\b).)+$

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

使用诸如[^ab]这样的字符类将匹配不在该字符集内的单个字符。(其中^是否定部分)。

要匹配不包含多字符序列ab的字符串,您需要使用负前向:

^(?:(?!ab).)+$
< p >
上面的表达式在regex注释模式下解析为:

(?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

正则表达式[^ab]将匹配例如'ab ab ab',但不匹配'ab',因为它将匹配字符串'a '或'b '。

你有什么语言/场景?你能从原始集合中减去结果,然后匹配ab吗?

如果您正在使用GNU grep,并且正在解析输入,则使用'-v'标志来反转结果,返回所有不匹配的结果。其他正则表达式工具也有“返回不匹配”功能。

如果我理解正确的话,你想要所有的东西,除了那些包含'ab'的项目。

最简单的方法是将否定完全从正则表达式中移除:

if (!userName.matches("^([Ss]ys)?admin$")) { ... }

是的,这叫做负前瞻。它是这样的——(?!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',因为查找的宽度为零(在大多数regex实现中)。

更多信息请访问页面

在这种情况下,我可能只是简单地避免正则表达式,并使用如下内容:

if (StringToTest.IndexOf("ab") < 0)
//do stuff

这可能也会快得多(上面对regex方法的快速测试表明,这种方法所花费的时间约为regex方法的25%)。一般来说,如果我知道我正在寻找的确切字符串,我发现正则表达式是多余的。因为你知道你不想要“ab”,所以测试字符串是否包含那个字符串很简单,不需要使用regex。

abc(?!def)将匹配没有遵循的abc by def,所以它匹配abce abc, abck,等等,如果我不想要def xyz也不会是abc(?!(def)(xyz)) ???< / p >

我也有同样的问题,并找到了解决方案:

abc(?:(?!def))(?:(?!xyz))

这些不可计数的组由“AND”组合在一起,所以这应该是可行的。希望能有所帮助。

只需在字符串中搜索“ab”,然后对结果求反:

!/ab/.test("bamboo"); // true
!/ab/.test("baobab"); // false

它看起来更简单,也应该更快。