2013-08-14 6 views
10

У меня есть следующие шаблоны, которые следует исключить.RegEx - Исключить совпадающие шаблоны

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 

Вышеуказанный образец соответствует всем перечисленным строкам. Теперь я хочу, чтобы он соответствовал всему остальному. Как мне это сделать?

Из поиска, кажется, мне нужно что-то вроде негативного взгляда/оглянуться назад. Но я действительно не понимаю. Может ли кто-нибудь указать мне в правильном направлении?

ответ

17

Вы можете просто положить его в негативном заглядывая вперёд так:

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

Просто так, не будет работать, хотя с тех пор, если вы делаете matches , он не будет Если вы делаете find , он будет соответствовать много раз, так как вы можете начать с множества мест в строке, где следующие символы не используются 't соответствует приведенному выше.

Чтобы это исправить, в зависимости от того, что вы хотите сделать, у нас есть 2 варианта:

  1. Если вы хотите, чтобы исключить все строки, которые точно один из них (то есть «сделать cheaperblahblah» не исключается), проверьте начало (^) и в конце ($) строки:

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

    .* (ноль или более дикие карты) является фактическое соответствие с местом. Отрицательный контроль вперед проверяется от первого символа.

  2. Если вы хотите, чтобы исключить все строки, содержащие один из них, вы можете убедиться, что упреждающая не соответствует перед каждым характером мы сопоставляем:

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

    Альтернатива добавить дикий - открытки к началу вашего ожидания (т. е.исключить все строки, которые с начала строки содержат что угодно, а затем ваш шаблон), но в настоящее время я не вижу в этом никакого преимущества (произвольный просмотр длины также менее вероятен для любого инструмента):

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

из-за ^ и $, либо делает find или matches будет работать на любой из выше (хотя, в случае matches, то ^ является необязательным и, в случае find, .* за пределами внешнего вида не является обязательным).


1: Несмотря на то, что они не могут быть названы, что многие языки имеют функции, эквивалентные matches и find с регулярным выражением.


Вышеупомянутый является строго регулярным ответом на этот вопрос.

Лучшим подходом может быть привязка к исходному регулярному выражению (mak(e|ing) ?it ?cheaper) и посмотреть, можете ли вы сгладить совпадения непосредственно с помощью инструмента или языка, который вы используете.

В Java, например, это связано с выполнением if (!string.matches(originalRegex)) (обратите внимание на !, что отрицает возвращаемое логическое значение) вместо if (string.matches(negLookRegex)).

6

Отрицательный взгляд, я считаю, это то, что вы ищете. Может быть, попробовать:

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

А может быть немного более гибким:

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

Только в случае, если есть более чем одно пространство.

Смежные вопросы