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

97

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

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

IAdapter
источник
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'
ДЭВИД АДЖАИ
источник