Как отрицать все регулярное выражение?


97

Например, у меня есть регулярное выражение (ma|(t){1}). Он совпадает maи tне совпадает bla.

Я хочу отрицать регулярное выражение, поэтому оно должно совпадать, blaа не maи t, добавляя что-то к этому регулярному выражению . Я знаю, что могу писать bla, но реальное регулярное выражение более сложное.


5
В стороне, {1}совершенно бесполезно. (Если вы думаете, что это дает некоторую ценность, почему бы вам не написать ((m{1}a{1}){1}|(t){1}){1}?)
tripleee

Ответы:


102

Используйте отрицательный поиск: (?!pattern)

Положительные поисковые запросы могут использоваться, чтобы утверждать, что шаблон соответствует. Отрицательный поиск противоположен: он используется для утверждения, что шаблон НЕ совпадает. Некоторые особенности подтверждают утверждения; некоторые накладывают ограничения на ретроспективный просмотр и т. д.

Ссылки на regular-expressions.info

Смотрите также

Еще примеры

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


2
regular-expressions.info - чертовски хороший ресурс для всех, что касается регулярных выражений.
Freiheit,

Что у всех есть поисковая поддержка? Не работает с grep.
Lazer

Pattern.compile("(?!(a.*b))").matcher("xab").matches()должно быть true, правда?
Карл Рихтер

4
Мне кажется, что это неправильно, см. Stackoverflow.com/questions/8610743/… для правильной альтернативы.
Карл Рихтер

57

Предполагая, что вы хотите запретить только строки, которые полностью соответствуют регулярному выражению (то есть, mmblaэто нормально, но mmнет), это то, что вы хотите:

^(?!(?:m{2}|t)$).*$

(?!(?:m{2}|t)$)отрицательный взгляд вперед ; он говорит: «начиная с текущей позиции, следующие несколько символов не являются mmили t, за которыми следует конец строки». Начальный якорь ( ^) в начале гарантирует, что просмотр вперед применяется в начале строки. Если это удастся, то .*продолжит и потребляет строку.

К вашему сведению, если вы используете matches()метод Java , вам действительно не нужны the ^и final $, но они не причиняют никакого вреда. Однако $внутренний просмотр вперед необходим.


2
Самая полезная часть этого ответа заключается в том, что вам нужно добавить .*в конец своего регулярного выражения, иначе он отклонит каждую строку.
Рав

2
$ Внутри отрицательного опережающего просмотра, и .*в конце оба являются критическими битами. Как всегда с RE, строгий набор модульных тестов абсолютно необходим для правильной работы. Этот ответ на 100% правильный.
Том Диббл,

1
\b(?=\w)(?!(ma|(t){1}))\b(\w*)

это для данного регулярного выражения.
\ b - найти границу слова.
положительный взгляд в будущее (? = \ w) здесь, чтобы избежать пробелов.
отрицательный взгляд вперед по сравнению с исходным регулярным выражением должен предотвратить его совпадения.
и, наконец, (\ w *) - это захват всех оставшихся слов.
группа, которая будет содержать слова, - это группа 3.
простой (?! шаблон) не будет работать, так как любая подстрока будет соответствовать
простой ^ (?! (?: m {2} | t) $). * $ будет не работает, поскольку его детализация - полные строки


0

Примените это, если вы используете laravel.

В Laravel есть not_regex, где проверяемое поле не должно соответствовать заданному регулярному выражению; preg_matchвнутренне использует функцию PHP .

'email' => 'not_regex:/^.+$/i'
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.