21

我要排除以下模式。

make it cheaper
make it cheapere
makeitcheaper.com.au
makeitcheaper
making it cheaper
www.make it cheaper
ww.make it cheaper.com

我创建了一个正则表达式来匹配其中的任何一个。但是,我想得到除这些之外的所有东西。我不确定如何反转我创建的这个正则表达式。

mak(e|ing) ?it ?cheaper

上面的模式匹配所有列出的字符串。现在我希望它与其他一切相匹配。我该怎么做?

从搜索结果来看,我似乎需要负前瞻/回顾之类的东西。但是,我真的不明白。有人能指出我正确的方向吗?

4

2 回答 2

31

你可以像这样把它放在一个消极的前瞻中:

(?!mak(e|ing) ?it ?cheaper)

就像那样是行不通的,因为如果你做matches1,它不会匹配,因为你只是向前看,你实际上并没有匹配任何东西,而且,如果你做find1,它会匹配很多时候,因为您可以从字符串中下一个字符与上述字符不匹配的许多地方开始。

要解决此问题,根据您的需要,我们有 2 种选择:

  1. 如果您想排除恰好是其中之一的所有字符串(即不排除“使其更便宜”),请检查字符串的开始(^)和结束($):

    ^(?!mak(e|ing) ?it ?cheaper$).*
    

    .*零个或多个通配符)是实际发生的匹配。从第一个字符开始的负前瞻检查。

  2. 如果要排除包含其中之一的所有字符串,可以确保在我们匹配的每个字符之前不匹配前瞻:

    ^((?!mak(e|ing) ?it ?cheaper).)*$
    

    另一种方法是在前瞻的开头添加通配符(即排除从字符串开头包含任何内容的所有字符串,然后是您的模式),但我目前看不出这有什么好处(任何给定工具也不太可能支持任意长度的前瞻):

    ^(?!.*mak(e|ing) ?it ?cheaper).*
    

由于^and $,执行 afind或 amatches将适用于上述任何一项(尽管在 的情况下matches, the^是可选的,而在 的情况下find.*外部预测是可选的)。


1:虽然它们可能不这么称呼,但许多语言具有与正则表达式等效的matches功能find


以上是这个问题的严格正则表达式答案。

更好的方法可能是坚持原来的正则表达式 ( mak(e|ing) ?it ?cheaper),看看您是否可以直接使用您正在使用的工具或语言来否定匹配。

例如,在 Java 中,这将涉及做if (!string.matches(originalRegex))(注意!,它否定返回的布尔值)而不是if (string.matches(negLookRegex)).

于 2013-08-14T20:24:34.203 回答
9

消极的前瞻,我相信是你正在寻找的。也许尝试:

(?!.*mak(e|ing) ?it ?cheaper)

也许更灵活一点:

(?!.*mak(e|ing) *it *cheaper)

以防万一有多个空间。

于 2013-08-14T20:23:49.917 回答