Як заперечувати цілий вираз?


95

У мене, наприклад, є регулярний вираз (ma|(t){1}). Це збігається maі tі не збігається bla.

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


5
Як сторону, {1}абсолютно марно. (Якщо ви думаєте, що це дає деяку цінність, чому б вам не написати ((m{1}a{1}){1}|(t){1}){1}?)
tripleee

Відповіді:


100

Використовуйте негативний пошук: (?!pattern)

Позитивні кругозірки можуть бути використані для твердження, що візерунок відповідає. Негативні кола пошуку - навпаки: використовується для твердження, що шаблон НЕ відповідає. Деякий смак підтримує твердження; деякі ставлять обмеження на вигляд позаду тощо.

Посилання на regular-expressions.info

Дивитися також

Більше прикладів

Це спроби придумати регекс-рішення для іграшкових проблем як вправ; вони повинні бути освітніми, якщо ви намагаєтеся вивчити різні способи використання значень навколо (вкладати їх, використовувати їх для зйомки тощо):


2
regular-expressions.info - проклятий хороший ресурс для всіх регексуючих речей.
Freiheit

Які всі підтримують орієнтування ? Не працює з grep.
Лазер

Pattern.compile("(?!(a.*b))").matcher("xab").matches()має бути true, правда?
Карл Ріхтер

4
Мені здається, це неправильно, див. Stackoverflow.com/questions/8610743/… для правильної альтернативи.
Карл Ріхтер

56

Якщо припустити, що ви хочете лише заборонити рядки, які повністю відповідають регексу (тобто mmblaце нормально, але mmце не так), це те, що ви хочете:

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

(?!(?:m{2}|t)$)є негативною лукахедом ; в ньому написано "починаючи з поточної позиції, наступні кілька символів не є mmабо з tнаступним кінцем рядка". Стартовий якір ( ^) на початку забезпечує, що lookahead застосовується на початку рядка. Якщо це вдасться, .*йде вперед і споживає рядок.

FYI, якщо ви використовуєте matches()метод Java , вам не потрібні справжні ^і остаточні $, але вони не приносять ніякої шкоди. Хоча $всередині lookahead потрібен.


2
Найбільш корисною частиною цієї відповіді є те, що ви повинні додати .*до кінця свого регулярного виразу, інакше він відхилить кожен рядок.
Рав

2
$ Усередині негативного випереджаючого перегляду, і .*в кінці обидва є критичними битами. Як завжди у випадку з РЕ, потужний набір модульних тестів є абсолютно важливим для того, щоб це виправити. Ця відповідь на 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.