正则表达式-排除匹配模式 [英] RegEx - Exclude Matched Patterns

查看:744
本文介绍了正则表达式-排除匹配模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要排除以下模式.

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

上述模式匹配所有列出的字符串.现在,我希望它与其他所有内容匹配.我该怎么办?

从搜索中看来,我需要类似否定的前瞻/回头.但是,我真的不明白.有人可以指出我正确的方向吗?

解决方案

您可以像这样将其置于否定的前瞻状态:

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

但是那样就行不通了,因为如果您执行matches 1 ,则由于您只是向前看而不会匹配,实际上并没有匹配任何东西,并且,如果您执行find 1 ,它将匹配很多次,因为您可以从字符串中很多位置开始,而下一个字符与上面的字符不匹配.

要解决此问题,我们有2种选择,具体取决于您要执行的操作:

  1. 如果要排除所有完全其中的一个字符串(即不排除"make it cheaperblahblah"),请检查开头(^)和结束($)的字符串:

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

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

  2. 如果要排除所有包含的字符串之一,则可以确保在匹配的每个字符之前都没有匹配先行查找:

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

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

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

由于^$,执行findmatches都适用于以上两种情况(尽管在matches的情况下,^是可选的, ,对于find而言,在前瞻之外的.*是可选的.)


1:尽管可能没有这么称呼,但是许多语言具有与matchesfind等价的带有正则表达式的功能.


上面是对这个问题的严格正则表达式答案.

一种更好的方法可能是坚持使用原始正则表达式(mak(e|ing) ?it ?cheaper),看看是否可以使用您所使用的工具或语言直接取消匹配.

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

I have the below patterns to be excluded.

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

I've created a regex to match any of these. However, I want to get everything else other than these. I am not sure how to inverse this regex I've created.

mak(e|ing) ?it ?cheaper

Above pattern matches all the strings listed. Now I want it to match everything else. How do I do it?

From the search, it seems I need something like negative lookahead / look back. But, I don't really get it. Can some one point me in the right direction?

解决方案

You can just put it in a negative look-ahead like so:

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

Just like that isn't going to work though since, if you do a matches1, it won't match since you're just looking ahead, you aren't actually matching anything, and, if you do a find1, it will match many times, since you can start from lots of places in the string where the next characters doesn't match the above.

To fix this, depending on what you wish to do, we have 2 choices:

  1. If you want to exclude all strings that are exactly one of those (i.e. "make it cheaperblahblah" is not excluded), check for start (^) and end ($) of string:

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

    The .* (zero or more wild-cards) is the actual matching taking place. The negative look-ahead checks from the first character.

  2. If you want to exclude all strings containing one of those, you can make sure the look-ahead isn't matched before every character we match:

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

    An alternative is to add wild-cards to the beginning of your look-ahead (i.e. exclude all strings that, from the start of the string, contain anything, then your pattern), but I don't currently see any advantage to this (arbitrary length look-ahead is also less likely to be supported by any given tool):

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

Because of the ^ and $, either doing a find or a matches will work for either of the above (though, in the case of matches, the ^ is optional and, in the case of find, the .* outside the look-ahead is optional).


1: Although they may not be called that, many languages have functions equivalent to matches and find with regex.


The above is the strictly-regex answer to this question.

A better approach might be to stick to the original regex (mak(e|ing) ?it ?cheaper) and see if you can negate the matches directly with the tool or language you're using.

In Java, for example, this would involve doing if (!string.matches(originalRegex)) (note the !, which negates the returned boolean) instead of if (string.matches(negLookRegex)).

这篇关于正则表达式-排除匹配模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆