如何否定整个正则表达式?


95

例如,我有一个正则表达式(ma|(t){1})。它匹配mat不匹配bla

我想否定正则表达式,因此必须匹配bla,而不是mat加入的东西此正则表达式。我知道我会写bla,但是实际的正则表达式却更复杂。


5
顺便说一句,{1}是完全没有用的。(如果您确实认为它提供了一些价值,那么为什么不写((m{1}a{1}){1}|(t){1}){1}?)
Tripleee

Answers:


100

使用否定环顾: (?!pattern)

正面环视可用于断言模式匹配。负面的反面是相反的:它用于断言模式不匹配。有些味道支持断言。有些限制了后视等等。

链接到regular-expressions.info

也可以看看

更多例子

这些都是为玩具问题练习提供正则表达式解决方案的尝试。如果您试图学习各种使用环视的方法(嵌套,使用它们进行捕捉等),则它们应该具有教育意义:


2
Regular-expressions.info对于所有正则表达式都是可恶的好资源。
Freiheit 2010年

什么都有环视支持?不适用于grep
拉泽尔

Pattern.compile("(?!(a.*b))").matcher("xab").matches()应该是true吧?
Karl Richter

4
我似乎不对,请参阅stackoverflow.com/questions/8610743/…以获取正确的选择。
Karl Richter

56

假设您只想禁止与正则表达式完全匹配的字符串(即mmbla可以,但mm不能),这就是您想要的:

^(?!(?:m{2}|t)$).*$

(?!(?:m{2}|t)$)是负面的前瞻 ; 它说:“从当前位置开始,接下来的几个字符不是 mmt,然后是字符串的结尾。” 开头的起始锚(^)确保在字符串的开头应用前瞻。如果成功,.*则继续并使用该字符串。

仅供参考,如果您使用Java的matches()方法,则实际上并不需要the ^和final $,但它们不会造成任何危害。但是,$内部必须是先行的。


2
此答案最有用的部分是您必须.*在正则表达式的末尾添加,否则它将拒绝每个字符串。
拉夫

2
$ 内部负先行,并.*在年底都是关键位。与RE一样,强大的单元测试集对于正确完成它绝对至关重要。这个答案是100%正确的。
汤姆·迪布尔

1
\b(?=\w)(?!(ma|(t){1}))\b(\w*)

这是给定的正则表达式。
\ b是查找单词边界。
前面的积极眼神(?= \ w)可以避免空格。
原始正则表达式的负面展望是防止其匹配。
最后(\ w *)将捕获所有剩余的单词。
包含单词的组是组3。
简单的(?!pattern)将不起作用,因为任何子字符串都将匹配
简单的^(?!(?: m {2} | t)$)。* $将不起作用,因为它的粒度是实线


0

如果您使用laravel,请套用这个。

Laravel有一个not_regex,其中正在验证的字段不得与给定的正则表达式匹配;在preg_match内部使用PHP 函数。

'email' => 'not_regex:/^.+$/i'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.