Регулярные выражения отрицание слова

этот вопрос уже есть ответ здесь:

Я пытаюсь что-то, что я чувствую, должно быть довольно очевидно для меня, но это не так. Я пытаюсь сопоставить строку, которая не содержит определенной последовательности символов. Я пробовал используя [^ab] , [^(ab)] , etc. чтобы соответствовать строки, содержащие ‘А или Б, или только А или только б или ‘бу’ но не матч на ‘АБ’. Примеры, которые я привел, не будут соответствовать "ab", это правда, но они также не будут соответствовать " a " в одиночку, и мне это нужно. Есть ли простой способ сделать это?

9 ответов

используйте отрицательный lookahead:

UPDATE: в комментариях ниже я заявил, что этот подход медленнее, чем тот, который приведен в Петровская. С тех пор я провел несколько тестов и обнаружил, что это действительно немного быстрее. Однако причина предпочесть эту технику другой — не скорость, а простота.

другая техника, описанная здесь как закаленный жадный токен, предназначен для более сложных проблемы, такие как сопоставление текста с разделителями, где разделители состоят из нескольких символов (например, HTML, как прокомментировал Люк ниже). Для проблемы, описанной в вопросе, это перебор.

для всех, кто заинтересован, я тестировал с большим куском текста Lorem Ipsum, подсчитывая количество строк, которые не содержат слова "quo". Это регексы, которые я использовал:

ищу ли я совпадения во всем тексте или разбиваю его на строки и сопоставьте их индивидуально, закрепленный lookahead последовательно превосходит плавающий.

использовать класс символов, таких как [^ab] будет соответствовать один символ, что не входит в набор символов. (С ^ будучи отрицающей частью).

чтобы соответствовать строке, которая не содержит многозначную последовательность ab , вы хотите использовать отрицательный просмотр вперед:

И приведенное выше выражение, отключенное в режиме комментариев regex:

Читайте также  Почему не могу зарегистрироваться в ватсапе

да его называют отрицательным взглядом. Вот как это звучит . —0—>. Так что abc(?!def) будет соответствовать abc не затем def. Таким образом, он будет соответствовать abce, abc, abck и т. д.

аналогично есть положительный lookahead — (?=regex here) . Так что abc(?=def) будет соответствовать abc, а затем def.

есть также отрицательный и положительный lookbehind — (? и (? соответственно

следует отметить, что отрицательный lookahead равен нулевой ширине. То есть, это не считайте, что заняли любое пространство.

так это может выглядеть как a(?=b)c будет соответствовать "abc", но это не будет. Он будет соответствовать "a", затем положительный lookahead с "b", но он не будет двигаться вперед в строку. Затем он попытается сопоставить " c " с "b", который не будет работать. Аналогично ^a(?=b)b$ будет соответствовать "ab", а не "abb", потому что lookarounds имеют нулевую ширину (в большинстве реализаций регулярных выражений).

подробнее о этой страница

использование регулярного выражения, как вы описали, является простым способом (насколько мне известно). Если вам нужен диапазон, вы можете использовать [^a-f].

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

abc(?!def) будет соответствовать abc не следует на деф. Так что это будет соответствовать abce, abc, abck, etc. что, если я не хочу ни def и xyz не будет abc(?!(def) (xyz)) .

у меня был тот же вопрос и нашел решение:

эти не подсчитывающие группы объединены "и", поэтому это должно сделать трюк. Надеюсь, это поможет.

регулярное выражение [^(ab)] будет соответствовать, например, "ab ab ab ab", но не "ab", потому что оно будет соответствовать строке " a " или "b".

какой язык / сценарий у вас есть? Можете ли вы вычесть результаты из исходного набора и просто сопоставить ab?

Если вы используете GNU grep и анализируете входные данные, используйте флаг ‘-v’ для инвертирования результатов, возвращая все несоответствия. Другие инструменты регулярных выражений также имеют функцию "return nonmatch".

Читайте также  Программа для извлечения текста из фотографий

Если я правильно понял, вы хотите все, кроме тех элементов, которые содержат " ab " в любом месте.

в этом случае я мог бы просто избежать регулярных выражений и пойти с что-то вроде:

Это, вероятно, также будет намного быстрее (быстрый тест против регулярных выражений выше показал, что этот метод занимает около 25% времени метода регулярных выражений). В общем, если я знаю точную строку, которую я ищу, я нашел, что regexes излишни. Поскольку вы знаете, что не хотите "ab", просто проверить, содержит ли строка эту строку, без использования регулярное выражение.

просто найдите " ab " в строке, затем отрицайте результат:

Преамбула

Регулярные выражения в программировании часто используются для валидации строк символов. Задача выяснить, удовлетворяет ли какая строка заданному выражению, довольно часто возникает при написании программ. Весьма распространены регулярки и во всяких конфигурационных файлах, настройках. Но если в тексте программы можно воспользоваться обычным оператором отрицания из языка программирования, в конфигах ситуация может быть сложнее. Допустим, нужно применить некоторую секцию конфигурации, только если строка с условием не начинается с некой подстроки, хотя синтаксис конфига позволяет только позитивную проверку (удовлетворяет ли строка регулярному выражению).

Итак, поскольку такая проблема слишком часто заводит меня в тупик, решил сформулировать её в более общем виде.

Постановка задачи

Пусть дано регулярное выражение R , содержащее любую, произвольную, заранее неизвестную комбинацию токенов, грамматически верную для движка PCRE. Требуется найти регулярное выражение !R , язык которого является дополнением для языка R . То есть любая строка, подходящая под R , не подходит под !R и наоборот.

Существует ли решение в общем виде? Если да, то предпочтительно включающее R в качестве подвыражения.

Читайте также  Сколько привязан телефон к стиму

Дата публикации: 2016-08-17

От автора: приветствую вас, друзья. В этой статье мы с вами познакомимся с еще одним метасимволом в регулярных выражениях — это метасимвол отрицания, который позволяет найти совпадение с любым символом, кроме заданных в символьном классе. Приступим?

Начнем с того, в каких случаях нам может потребоваться символ отрицания. Классический вариант, когда мы открыли некий парный символ, например кавычки, и внутри кавычек нам подходят любые символы, кроме, собственно, кавычек. Вот здесь нам и пригодится символ отрицания.

Как же обозначается этот символ в регулярных выражениях? На самом деле он уже вам знаком. Это циркумфлекс, который по простому часто называют крышкой или домиком. Записывается он так — ^. Постойте, скажете вы, ведь этот символ обозначает начало строки в регулярках. Все верно. Но этот символ также является и символом отрицания.

Как трактовать этот метасимвол — зависит от его позиции в регулярном выражении. Если он стоит самым первым в регулярке, то есть идет сразу после ограничителя шаблона, тогда это метасимвол начала строки. Если же он используется в самом начале символьного класса — [^. ] — в этом случае он интерпретируется как символ отрицания и сообщает, что все символы, идущие после него, не должны встречаться в совпадающей позиции строки. Во всех прочих случаях этот символ совпадает сам с собой, то есть не является метасимволом.

Ну и давайте решим задачу, озвученную выше, — найдем все ссылки в тексте:

Бесплатный курс по PHP программированию

Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC

В курсе 39 уроков | 15 часов видео | исходники для каждого урока

Ссылка на основную публикацию
Adblock
detector