регулярные выражения php отрицание
Регулярные выражения в PHP. Символ отрицания
Дата публикации: 2016-08-17
От автора: приветствую вас, друзья. В этой статье мы с вами познакомимся с еще одним метасимволом в регулярных выражениях — это метасимвол отрицания, который позволяет найти совпадение с любым символом, кроме заданных в символьном классе. Приступим?
Начнем с того, в каких случаях нам может потребоваться символ отрицания. Классический вариант, когда мы открыли некий парный символ, например кавычки, и внутри кавычек нам подходят любые символы, кроме, собственно, кавычек. Вот здесь нам и пригодится символ отрицания.
Как же обозначается этот символ в регулярных выражениях? На самом деле он уже вам знаком. Это циркумфлекс, который по простому часто называют крышкой или домиком. Записывается он так — ^. Постойте, скажете вы, ведь этот символ обозначает начало строки в регулярках. Все верно. Но этот символ также является и символом отрицания.
Как трактовать этот метасимвол — зависит от его позиции в регулярном выражении. Если он стоит самым первым в регулярке, то есть идет сразу после ограничителя шаблона, тогда это метасимвол начала строки. Если же он используется в самом начале символьного класса — [^. ] — в этом случае он интерпретируется как символ отрицания и сообщает, что все символы, идущие после него, не должны встречаться в совпадающей позиции строки. Во всех прочих случаях этот символ совпадает сам с собой, то есть не является метасимволом.
Ну и давайте решим задачу, озвученную выше, — найдем все ссылки в тексте:
Бесплатный курс по PHP программированию
Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC
В курсе 39 уроков | 15 часов видео | исходники для каждого урока
Шпаргалка по регулярным выражениям
Квантификаторы
Аналог | Пример | Описание | |
---|---|---|---|
? | a? | одно или ноль вхождений «а» | |
+ | a+ | одно или более вхождений «а» | |
* | a* | ноль или более вхождений «а» |
Модификаторы
Символ «минус» (-) меред модификатором (за исключением U) создаёт его отрицание.
Спецсимволы
Аналог | Описание | |
---|---|---|
() | подмаска, вложенное выражение | |
[] | групповой символ | |
количество вхождений от «a» до «b» | ||
| | логическое «или», в случае с односимвольными альтернативами используйте [] | |
\ | экранирование спец символа | |
. | любой сивол, кроме перевода строки | |
\d | 5 | десятичная цифра |
\D | [^\d] | любой символ, кроме десятичной цифры |
\f | конец (разрыв) страницы | |
\n | перевод строки | |
\pL | буква в кодировке UTF-8 при использовании модификатора u | |
\r | возврат каретки | |
\s | [ \t\v\r\n\f] | пробельный символ |
\S | [^\s] | любой символ, кроме промельного |
\t | табуляция | |
\w | [0-9a-z_] | любая цифра, буква или знак подчеркивания |
\W | [^\w] | любой символ, кроме цифры, буквы или знака подчеркивания |
\v | вертикальная табуляция |
Спецсимволы внутри символьного класса
Пример | Описание | |
---|---|---|
^ | [^da] | отрицание, любой символ кроме «d» или «a» |
— | [a-z] | интервал, любой симво от «a» до «z» |
Позиция внутри строки
Якоря
Якоря в регулярных выражениях указывают на начало или конец чего-либо. Например, строки или слова. Они представлены определенными символами. К примеру, шаблон, соответствующий строке, начинающейся с цифры, должен иметь следующий вид:
Здесь символ ^ обозначает начало строки. Без него шаблон соответствовал бы любой строке, содержащей цифру.
Символьные классы
Символьные классы в регулярных выражениях соответствуют сразу некоторому набору символов. Например, \d соответствует любой цифре от 0 до 9 включительно, \w соответствует буквам и цифрам, а \W — всем символам, кроме букв и цифр. Шаблон, идентифицирующий буквы, цифры и пробел, выглядит так:
POSIX
POSIX — это относительно новое дополнение семейства регулярных выражений. Идея, как и в случае с символьными классами, заключается в использовании сокращений, представляющих некоторую группу символов.
Утверждения
Поначалу практически у всех возникают трудности с пониманием утверждений, однако познакомившись с ними ближе, вы будете использовать их довольно часто. Утверждения предоставляют способ сказать: «я хочу найти в этом документе каждое слово, включающее букву “q”, за которой не следует “werty”».
Итак, парсер проверяет несколько следующих символов по предложенному шаблону ( werty ). Если они найдены, то утверждение ложно, а значит символ q будет «проигнорирован», т. е. не будет соответствовать шаблону. Если же werty не найдено, то утверждение верно, и с q все в порядке. Затем продолжается поиск любых символов, кроме пробела ( [^\s]* ).
Кванторы
Кванторы позволяют определить часть шаблона, которая должна повторяться несколько раз подряд. Например, если вы хотите выяснить, содержит ли документ строку из от 10 до 20 (включительно) букв «a», то можно использовать этот шаблон:
Этот шаблон соответствует тексту, заключенному в двойные кавычки. Однако, ваша исходная строка может быть вроде этой:
Приведенный выше шаблон найдет в этой строке вот такую подстроку:
Он оказался слишком жадным, захватив наибольший кусок текста, который смог.
Экранирование в регулярных выражениях
Знак экранирования, предшествующий символу вроде точки, заставляет парсер игнорировать его функцию и считать обычным символом. Есть несколько символов, требующих такого экранирования в большинстве шаблонов и языков. Вы можете найти их в правом нижнем углу шпаргалки («Мета-символы»).
Шаблон для нахождения точки таков:
Другие специальные символы в регулярных выражениях соответствуют необычным элементам в тексте. Переносы строки и табуляции, к примеру, могут быть набраны с клавиатуры, но вероятно собьют с толку языки программирования. Знак экранирования используется здесь для того, чтобы сообщить парсеру о необходимости считать следующий символ специальным, а не обычной буквой или цифрой.
Спецсимволы экранирования в регулярных выражениях
Подстановка строк
Подстановка строк подробно описана в следующем параграфе «Группы и диапазоны», однако здесь следует упомянуть о существовании «пассивных» групп. Это группы, игнорируемые при подстановке, что очень полезно, если вы хотите использовать в шаблоне условие «или», но не хотите, чтобы эта группа принимала участие в подстановке.
Группы и диапазоны
Группы и диапазоны очень-очень полезны. Вероятно, проще будет начать с диапазонов. Они позволяют указать набор подходящих символов. Например, чтобы проверить, содержит ли строка шестнадцатеричные цифры (от 0 до 9 и от A до F), следует использовать такой диапазон:
Чтобы проверить обратное, используйте отрицательный диапазон, который в нашем случае подходит под любой символ, кроме цифр от 0 до 9 и букв от A до F:
Группы наиболее часто применяются, когда в шаблоне необходимо условие «или»; когда нужно сослаться на часть шаблона из другой его части; а также при подстановке строк.
Использовать «или» очень просто: следующий шаблон ищет «ab» или «bc»:
Первым параметром будет примерно такой шаблон (возможно вам понадобятся несколько дополнительных символов для этой конкретной функции):
Он найдет любые вхождения слова «wish» вместе с предыдущим и следующим символами, если только это не буквы или цифры. Тогда ваша подстановка может быть такой:
Модификаторы шаблонов
Модификаторы шаблонов используются в нескольких языках, в частности, в Perl. Они позволяют изменить работу парсера. Например, модификатор i заставляет парсер игнорировать регистры.
Регулярные выражения в Perl обрамляются одним и тем же символом в начале и в конце. Это может быть любой символ (чаще используется «/»), и выглядит все таким образом:
Модификаторы добавляются в конец этой строки, вот так:
Мета-символы
Наконец, последняя часть таблицы содержит мета-символы. Это символы, имеющие специальное значение в регулярных выражениях. Так что если вы хотите использовать один из них как обычный символ, то его необходимо экранировать. Для проверки наличия скобки в тексте, используется такой шаблон:
Шпаргалка представляет собой общее руководство по шаблонам регулярных выражений без учета специфики какого-либо языка. Она представлена в виде таблицы, помещающейся на одном печатном листе формата A4. Создана под лицензией Creative Commons на базе шпаргалки, автором которой является Dave Child. Скачать в PDF, PNG.
Шпаргалка по регулярным выражениям. В примерах
Jan 6, 2019 · 5 min read
Регулярные выражения (regex или regexp) очень эффективны для извлечения информации из текста. Для этого нужно произвести поиск одного или нескольких совпадений по определённому шаблону (т. е. определённой последовательности символов ASCII или unicode).
Области применения regex разнообразны, от валидации до парсинга/замены строк, передачи данных в другие форматы и Web Scraping’а.
Одна из любопытных особенностей регулярных выражени й в их универсальности, стоит вам выучить синтаксис, и вы сможете применять их в любом (почти) языке программирования (JavaScript, Java, VB, C #, C / C++, Python, Perl, Ruby, Delphi, R, Tcl, и многих других). Небольшие отличия касаются только наиболее продвинутых функций и версий синтаксиса, поддерживаемых движком.
Давайте начнём с нескольких примеров.
Основы
Оператор ИЛИ — | или []
Флаги
Мы научились строить регулярные выражения, но забыли о фундаментальной концепции ― флагах.
Средний уровень
Скобочные группы ― ()
Этот оператор очень полезен, когда нужно извлечь информацию из строк или данных, используя ваш любимый язык программирования. Любые множественные совпадения, по нескольким группам, будут представлены в виде классического массива: доступ к их значениям можно получить с помощью индекса из результатов сопоставления.
Скобочные выражения ― []
Помните, что внутри скобочных выражений все специальные символы (включая обратную косую черту \ ) теряют своё служебное значение, поэтому нам ненужно их экранировать.
Жадные и ленивые сопоставления
Квантификаторы ( * + <> ) ― это «жадные» операторы, потому что они продолжают поиск соответствий, как можно глубже ― через весь текст.
Например, выражение соответствует
Продвинутый уровень
Границы слов ― \b и \B
Регулярные выражения и отрицание целой группы символов [дубликат]
этот вопрос уже есть ответ здесь:
9 ответов
используйте отрицательный lookahead:
другая техника, описанная здесь как закаленный жадный токен, предназначен для более сложных проблемы, такие как сопоставление текста с разделителями, где разделители состоят из нескольких символов (например, HTML, как прокомментировал Люк ниже). Для проблемы, описанной в вопросе, это перебор.
для всех, кто заинтересован, я тестировал с большим куском текста Lorem Ipsum, подсчитывая количество строк, которые не содержат слова «quo». Это регексы, которые я использовал:
ищу ли я совпадения во всем тексте или разбиваю его на строки и сопоставьте их индивидуально, закрепленный lookahead последовательно превосходит плавающий.
использовать класс символов, таких как [^ab] будет соответствовать один символ, что не входит в набор символов. (С ^ будучи отрицающей частью).
И приведенное выше выражение, отключенное в режиме комментариев regex:
следует отметить, что отрицательный lookahead равен нулевой ширине. То есть, это не считайте, что заняли любое пространство.
так это может выглядеть как a(?=b)c будет соответствовать «abc», но это не будет. Он будет соответствовать «a», затем положительный lookahead с «b», но он не будет двигаться вперед в строку. Затем он попытается сопоставить » c » с «b», который не будет работать. Аналогично ^a(?=b)b$ будет соответствовать «ab», а не «abb», потому что lookarounds имеют нулевую ширину (в большинстве реализаций регулярных выражений).
подробнее о этой страница
использование регулярного выражения, как вы описали, является простым способом (насколько мне известно). Если вам нужен диапазон, вы можете использовать [^a-f].
самый простой способ-полностью вытащить отрицание из регулярного выражения:
у меня был тот же вопрос и нашел решение:
эти не подсчитывающие группы объединены «и», поэтому это должно сделать трюк. Надеюсь, это поможет.
регулярное выражение [^(ab)] будет соответствовать, например, «ab ab ab ab», но не «ab», потому что оно будет соответствовать строке » a » или «b».
какой язык / сценарий у вас есть? Можете ли вы вычесть результаты из исходного набора и просто сопоставить ab?
Если вы используете GNU grep и анализируете входные данные, используйте флаг ‘-v’ для инвертирования результатов, возвращая все несоответствия. Другие инструменты регулярных выражений также имеют функцию «return nonmatch».
Если я правильно понял, вы хотите все, кроме тех элементов, которые содержат » ab » в любом месте.
в этом случае я мог бы просто избежать регулярных выражений и пойти с что-то вроде:
Это, вероятно, также будет намного быстрее (быстрый тест против регулярных выражений выше показал, что этот метод занимает около 25% времени метода регулярных выражений). В общем, если я знаю точную строку, которую я ищу, я нашел, что regexes излишни. Поскольку вы знаете, что не хотите «ab», просто проверить, содержит ли строка эту строку, без использования регулярное выражение.
просто найдите » ab » в строке, затем отрицайте результат:
Регулярные выражения в PHP.
Регулярные выражения позволяют найти в строке последовательности, соответствующие шаблону. Например шаблон «Вася(.*)Пупкин» позволит найти последовательность когда между словами Вася и Пупкин будет любое количество любых символов. Если надо найти шесть цифр, то пишем «4<6>» (если, например, от шести до восьми цифр, тогда «2<6,8>«). Здесь разделены такие вещи как указатель набора символов и указатель необходимого количества:
Как всякий гибкий инструмент, регулярные выражения гибки, но не абсолютно: зона их применения ограничена. Например, если вам надо заменить в тексте одну фиксированную строку на другую, фиксированную опять же, пользуйтесь str_replace. Разработчики php слезно умоляют не пользоваться ради этого сложными функциями ereg_replace или preg_replace, ведь при их вызове происходит процесс интерпретации строки, а это серьезно потребляет ресурсы системы. К сожалению, это любимые грабли начинающих php-программистов.
Набор символов
Не пользуйтесь классом символов для обозначения всего лишь одного (вместо «[ ]+» вполне сойдет » +»). Не пишите в классе символов точку это ведь любой символ, тогда другие символы в классе будут просто лишними (а в негативном классе получится отрицание всех символов).
Квантификатор
Квантификатором можно указать как конкретное значение, так и пределы. Если число заданных подпадает под пределы квантификатора, фрагмент выражения считается совпавшим с разбираемой строкой. Синтаксис:
Если нужно указать только необходимый минимум, а максимума нет, просто ставим запятую и не пишем второе число: «<5,>» («минимум 5»). Для наиболее часто употребляемых квантификаторов есть специальные обозначения:
* | «звёздочка» или знак умножения |
+ | плюс |
? | вопросительный знак |
На практике такие символы используются чаще, чем фигурные скобки.
Якоря
Эти символы должны стоять соответственно в самом начале и в самом конце строки.
Жадность
Вопросительный знак выступает еще и как минимизатор квантификатора:
.*?
Результат работы примера:
Строка шаблона, как вы уже заметили, начинается и заканчивается слэшами. После второго идут параметры:
i | регистронезависимый поиск |
m | |
s | символ «.» (точка) совпадает и с переносом строки (по умолчанию нет) |
A | привязка к началу текста |
E | заставляет символ «$» совпадать только с концом текста. Игнорируется, если установлен парамерт m. |
U | Инвертирует «жадность» для каждого квантификатора (если же после квантификатора стоит «?», этот квантификатор перестает быть «жадным»). |
e | Строка замены интерпретитуется как PHP код. |
Функции для работы с регулярными выражениями
preg_grep
array preg_grep (string pattern, array input [, int flags])
preg_grep() возвращает массив, состоящий из элементов входящего массива input, которые соответствуют заданному шаблону pattern.
Параметр flags может принимать следующие значения:
PREG_GREP_INVERT
В случае, если этот флаг установлен, функция preg_grep(), возвращает те элементы массива, которые не соответствуют заданному шаблону pattern.
Результат, возвращаемый функцией preg_grep() использует те же индексы, что и массив исходных данных. Если такое поведение вам не подходит, примените array_values() к массиву, возвращаемому preg_grep() для реиндексации.
Пример кода:
preg_match
int preg_match ( string pattern, string subject [, array matches [, int flags [, int offset]]]) Ищет в заданном тексте subject совпадения с шаблоном pattern
flags может принимать следующие значения:
Функция preg_match() возвращает количество найденных соответствий. Это может быть 0 (совпадения не найдены) и 1, поскольку preg_match() прекращает свою работу после первого найденного совпадения. Если необходимо найти либо сосчитать все совпадения, следует воспользоваться функцией preg_match_all(). Функция preg_match() возвращает FALSE в случае, если во время выполнения возникли какие-либо ошибки.
Рекомендация: Не используйте функцию preg_match(), если необходимо проверить наличие подстроки в заданной строке. Используйте для этого strpos() либо strstr(), поскольку они выполнят эту задачу гораздо быстрее.
Пример кода
Пример кода
Пример кода
preg_match_all
int preg_match_all (string pattern, string subject, array matches [, int flags [, int offset]])
Ищет в строке subject все совпадения с шаблоном pattern и помещает результат в массив matches в порядке, определяемом комбинацией флагов flags.
После нахождения первого соответствия последующие поиски будут осуществляться не с начала строки, а от конца последнего найденного вхождения.
Дополнительный параметр flags может комбинировать следующие значения (необходимо понимать, что использование PREG_PATTERN_ORDER одновременно с PREG_SET_ORDER бессмысленно):
Пример кода
Пример кода
В случае, если никакой флаг не используется, по умолчанию используется PREG_PATTERN_ORDER.
Возвращает количество найденных вхождений шаблона (может быть нулем) либо FALSE, если во время выполнения возникли какие-либо ошибки.
Пример кода
Пример кода
preg_quote
string preg_quote (string str [, string delimiter])
Функция preg_quote() принимает строку str и добавляет обратный слеш перед каждым служебным символом. Это бывает полезно, если в составлении шаблона участвуют строковые переменные, значение которых в процессе работы скрипта может меняться.
В случае, если дополнительный параметр delimiter указан, он будет также экранироваться. Это удобно для экранирования ограничителя, который используется в PCRE функциях. Наиболее распространенным ограничителем является символ ‘/’.
Пример кода
Пример кода
preg_replace
mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit])
При использовании замены по шаблону с использованием ссылок на подмаски может возникнуть ситуация, когда непосредственно за маской следует цифра. В таком случае нотация вида \\n приводит к ошибке: ссылка на первую подмаску, за которой следует цифра 1, запишется как \\11, что будет интерпретировано как ссылка на одиннадцатую подмаску. Это недоразумение можно устранить, если воспользоваться конструкцией \$<1>1, указывающей на изолированную ссылку на первую подмаску, и следующую за ней цифру 1.
Результатом работы этого примера будет:
Если во время выполнения функции были обнаружены совпадения с шаблоном, будет возвращено измененное значение subject, в противном случае будет возвращен исходный текст subject.
Первые три параметра функции preg_replace() могут быть одномерными массивами. В случае, если массив использует ключи, при обработке массива они будут взяты в том порядке, в котором они расположены в массиве. Указание ключей в массиве для pattern и replacement не является обязательным. Если вы все же решили использовать индексы, для сопоставления шаблонов и строк, участвующих в замене, используйте функцию ksort() для каждого из массивов.
В случае, если параметр subject является массивом, поиск и замена по шаблону производятся для каждого из его элементов. Возвращаемый результат также будет массивом.
Модификатор /e меняет поведение функции preg_replace() таким образом, что параметр replacement после выполнения необходимых подстановок интерпретируется как PHP-код и только после этого используется для замены. Используя данный модификатор, будьте внимательны: параметр replacement должен содержать корректный PHP-код, в противном случае в строке, содержащей вызов функции preg_replace(), возникнет ошибка синтаксиса.
Пример кода: Замена по нескольким шаблонам
Этот пример выведет:
Пример кода: Использование модификатора /e
Пример кода: Преобразует все HTML-теги к верхнему регистру
preg_replace_callback
mixed preg_replace_callback (mixed pattern, callback callback, mixed subject [, int limit])
Пример кода
preg_split
array preg_split (string pattern, string subject [, int limit [, int flags]])
Возвращает массив, состоящий из подстрок заданной строки subject, которая разбита по границам, соответствующим шаблону pattern.
flags может быть произвольной комбинацией следующих флагов (соединение происходит при помощи оператора ‘|’):
PREG_SPLIT_NO_EMPTY
В случае, если этот флаг указан, функция preg_split() вернет только непустые подстроки.
PREG_SPLIT_DELIM_CAPTURE
В случае, если этот флаг указан, выражение, заключенное в круглые скобки в разделяющем шаблоне, также извлекается из заданной строки и возвращается функцией. Этот флаг был добавлен в PHP 4.0.5.
Примеры кода
В случае, если после открывающей круглой скобки следует «?:«, захват строки не происходит, и текущая подмаска не нумеруется. Например, если строка «the white queen» сопоставляется с шаблоном the ((?:red|white) (king|queen)), будут захвачены подстроки «white queen» и «queen», и они будут пронумерованы 1 и 2 соответственно: