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

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

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


person San    schedule 14.08.2013    source источник


Ответы (2)


Вы можете просто поместить это в отрицательный прогноз следующим образом:

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

Так же, как это не сработает, поскольку, если вы выполните matches 1, он не будет соответствовать, так как вы просто смотрите вперед, вы на самом деле ничего не сопоставляете, и, если вы выполняете find 1, он будет соответствовать много раз, поскольку вы можете начать с множества мест в строке, где следующие символы не совпадают с указанными выше.

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

  1. Если вы хотите исключить все строки, которые точно являются одними из них (т.е. "сделать это дешевлебла-бла" не исключается), проверьте начало (^) и конец ($) строки:

    ^(?!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)).

person Bernhard Barker    schedule 14.08.2013

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

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

И, может быть, немного гибче:

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

На всякий случай пробелов больше одного.

person Jerry    schedule 14.08.2013