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
Выше шаблон соответствует всем перечисленным строкам. Теперь я хочу, чтобы это соответствовало всему остальному. Как мне это сделать?
Из поиска, кажется, мне нужно что-то вроде негативного взгляда / оглянуться назад. Но я не совсем понимаю. Кто-нибудь может указать мне правильное направление?
2 ответа
Вы можете просто поставить это в негативном прогнозе, например, так:
(?!mak(e|ing) ?it ?cheaper)
Просто так не будет работать, хотя, так как, если вы делаете matches
1, он не будет совпадать, так как вы просто смотрите вперед, на самом деле вы ничего не соответствуете, и, если вы делаете find
1, он будет совпадать много раз, так как вы можете начать с множества мест в строке, где следующие символы не соответствуют вышеприведенному.
Чтобы это исправить, в зависимости от того, что вы хотите сделать, у нас есть 2 варианта:
Если вы хотите исключить все строки, которые точно относятся к одной из них (то есть "сделать его дешевле, не исключено"), проверьте запуск (
^
) и конец ($
) строки:^(?!mak(e|ing) ?it ?cheaper$).*
.*
(ноль или более подстановочных знаков) - фактическое совпадение. Отрицательный прогнозный чек от первого символа.Если вы хотите исключить все строки, содержащие одну из них, вы можете убедиться, что упреждающий просмотр не сопоставляется перед каждым сопоставляемым символом:
^((?!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))
,
Негативный взгляд, я думаю, это то, что вы ищете. Может быть, попробуйте:
(?!.*mak(e|ing) ?it ?cheaper)
И, может быть, немного более гибким:
(?!.*mak(e|ing) *it *cheaper)
На всякий случай есть более одного пробела.