RegEx - 排除匹配模式

时间:2013-08-14 20:17:36

标签: regex regex-lookarounds negative-lookahead lookaround

我要排除以下模式。

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

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

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

2 个答案:

答案 0 :(得分:23)

你可以像这样把它放在负面的预测中:

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

就像那样不会起作用,因为如果你做matches 1 ,它就不会匹配,因为你只是向前看,你不是实际上匹配任何东西,并且,如果你执行find 1 ,它将匹配很多次,因为你可以从字符串中的许多地方开始,其中下一个字符与下一个字符不匹配上方。

要解决这个问题,根据您的目的,我们有两个选择:

  1. 如果您要排除其中一个完全的所有字符串(即“不要将其设为cheaperblahblah”),请检查开始(^)并结束($)字符串:

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

    .*(零个或多个通配符)是发生的实际匹配。来自第一个角色的负向前瞻检查。

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

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

    另一种方法是在你的预测开始时添加通配符(即排除从字符串开头包含任何内容,然后是你的模式的所有字符串),但我目前看不到任何优势对此(任意给定工具也不太可能支持任意长度前瞻):

    ^(?!.*mak(e|ing) ?it ?cheaper).*
    
  3. 由于^$,执行findmatches将适用于上述任何一种情况(但在{{1}的情况下} {},matches是可选的,如果是^,则前瞻之外的find是可选的。


    1:虽然它们可能不被称为,但许多语言的函数等同于.*matches的正则表达式。


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

    更好的方法可能是坚持使用原始正则表达式(find)并查看是否可以直接使用您正在使用的工具或语言来否定匹配。

    例如,在Java中,这将涉及执行mak(e|ing) ?it ?cheaper(请注意if (!string.matches(originalRegex)),否定返回的布尔值)而不是!

答案 1 :(得分:7)

负面的向前看,我相信你正在寻找的东西。也许试试:

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

也许更灵活一点:

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

以防有多个空格。