Регулярные выражения PHP. PHP (регулярное выражение) - что это такое? Примеры и проверка регулярных выражений Регулярные выражения php любые символы
Регулярные выражения - это специальные шаблоны для поиска подстроки в тексте. С их помощью можно решить одной строчкой такие задачи: «проверить, содержит ли строка цифры», «найти в тексте все адреса email», «заменить несколько идущих подряд знаков вопроса на один».
Начнем с одной народной программистской мудрости:
Некоторые люди, сталкиваясь с проблемой, думают: «Ага, я умный, я решу её с помощью регулярных выражений». Теперь у них две проблемы. Примеры шаблоновНачнем с пары простых примеров. Первое выражение на картинке ниже ищет последовательность из 3 букв, где первая буква это «к», вторая - любая русская буква и третья - это «т» без учета регистра (например, «кот» или «КОТ» подходит под этот шаблон). Второе выражение ищет в тексте время в формате 12:34 .
Любое выражение начинается с символа-ограничителя (delimiter по англ.). В качестве него обычно используют символ / , но можно использовать и другие символы, не имеющие специального назначения в регулярках, например, ~ , # или @ . Альтернативные разделители используют, если в выражении может встречаться символ / . Затем идет сам шаблон строки, которую мы ищем, за ним второй ограничитель и в конце может идти одна или несколько букв-флагов. Они задают дополнительные опции при поиске текста. Вот примеры флагов:
- i - говорит, что поиск должен вестись без учета регистра букв (по умолчанию регистр учитывается)
- u - говорит, что выражение и текст, по которому идет поиск, исплоьзуют кодировку utf-8, а не только латинские буквы. Без него поиск русских (и любых других нелатинских) символов может работать некорректно, потому стоит ставить его всегда.
Сам шаблон состоит из обычных символов и специальных конструкций. Ну например, буква «к» в регулярках обозначает саму себя, а вот символы значат «в этом месте может быть любая цифра от 0 до 5». Вот полный список специальных символов (в мануале php их называют метасимволы), а все остальные символы в регулярке - обычные:
Ниже мы разберем значение каждого из этих символов (а также объясним почему буква «ё» вынесена отдельно в первом выражении), а пока попробуем применить наши регулярки к тексту и посмотреть, что выйдет. В php есть специальная функция preg_match($regexp, $text, $match) , которая принимает на вход регулярку, текст и пустой массив. Она проверяет, есть ли в тексте подстрока, соответствующая данному шаблону и возвращает 0 , если нет, или 1 , если она есть. А в переданный массив в элемент с индексом 0 кладется первое найденное совпадение с регуляркой. Напишем простую программу, применяющую регулярные выражения к разным строкам:
Познакомившись с примером, изучим регулярные выражения более подробно.
Скобки в регулярных выраженияхДавай повторим, что обозначают разные виды скобок:
- Фигурные скобки a{1,5} задают число повторений предыдущего символа - в этом примере выражение ищет от 1 до 5 идущих подряд букв «a»
- Квадратные скобки означают «один любой из этих символов», в данном случае - буквы a, b, c, x, y, z или цифра от 0 до 5. Внутри квадратных скобок не работают другие спецсимволы вроде | или * - они обозначают обычный символ. Если в квадратных скобках в начале стоит символ ^ то смысл меняется на противоположный: «любой один символ, кроме указанных» - например [^a-c] значит «один любой символ, кроме a, b или c».
- Круглые скобки группируют символы и выражения. Например в выражении abc+ знак «плюс» относится только к букве c и это выражение ищет слова вроде abc, abcc, abccc. А если поставить скобки a(bc)+ то квантифиактор плюс относится уже к последовательности bc и выражение ищет слова abc, abcbc, abcbcbc
Примечание: в квадратных скобках можно указывать диапазоны символов, но помни, что русская буква ё идет отдельно от алфавита и чтобы написать «любая русская буква», надо писать [а-яё] .
БекслешиЕсли ты смотрел другие учебники по регулярным выражениям, то наверно заметил, что бекслеш везде пишут по-разному. Где-то пишут один бекслеш: \d , а здесь в примерах он повторен 2 раза: \\d . Почему?
Язык регулярных выражений требует писать бекслеш один раз. Однако в строках в одиночных и двойных кавычках в PHP бекслеш тоже имеет особое значение: мануал про строки . Ну например, если написать $x = "\$"; то PHP воспримет это как специальную комбинацию и вставит в строку только символ $ (и движок регулярных выражений не узнает о бекслеше перед ним). Чтобы вставить в строку последовательность \$ , мы должны удвоить бекслеш и записать код в виде $x = "\\$"; .
По этой причине в некоторых случаях (там, где последовательность символов имеет специальный смысл в PHP) мы обязаны удваивать бекслеш:
- Чтобы написать в регулярке \$ , мы пишем в коде "\\$"
- Чтобы написать в регулярке \\ , мы удваиваем каждый бекслеш и пишем "\\\\"
- Чтобы написать в регулярке бекслеш и цифру (\1), бекслеш надо удвоить: "\\1"
В остальных случаях один или два бекслеша дадут один и тот же результат: "\\d" и "\d" вставят в строку пару символов \d - в первом случае 2 бекслеша это последовательность для вставки бекслеша, во втором случае специальной последовательности нет и символы вставятся как есть. Проверить, какие символы вставятся в строку, и что увидит движок регулярных выражений, можно с помощью echo: echo "\$"; . Да, сложно, а что поделать?
Специальные конструкции в регулярках- \d ищет одну любую цифру, \D - один любой символ, кроме цифры
- \w соответствует одной любой букве (любого алфавита), цифре или знаку подчеркивания _ . \W соответствует любому символу, кроме буквы, цифры, знака подчеркивания.
Также, есть удобное условие для указания на границу слова: \b . Эта конструкция обозначает, что с одной стороны от нее должен стоять символ, являющийся буквой/цифрой/знаком подчеркивания (\w), а с другой стороны - не являющийся. Ну, например, мы хотим найти в тексте слово «кот». Если мы напишем регулярку /кот/ui , то она найдет последовательность этих букв в любом месте - например, внутри слова «скотина». Это явно не то, что мы хотели. Если же мы добавим условие границы слова в регулярку: /\bкот\b/ui , то теперь искаться будет только отдельно стоящее слово «кот».
Мануал- Синтаксис регулярных выражений в PHP , подробное описание
Регулярные выражения (сокращенно — regex ) представляют собой последовательности символов, которые формируют шаблоны поиска. В основном они используются в шаблонах сопоставления со строками.
Краткая история
- Все началось в 1940 — 1960-х годах, когда множество умных людей говорили о регулярных выражениях;
- 1970-е годы g / re / p;
- 1980 Perl и Генри Спенсер;
- 1997 PCRE (регулярные выражения, совместимые с Perl). Именно тогда начался взлет того, что мы называем регулярные выражения. PCRE предоставляет библиотеки почти для каждого языка.
PHP включает в себя три основные функции для работы с PCRE — preg_match , preg_match_all и preg_replace .
Сравнение соответствия
Выражение возвращает 1 , если соответствие установлено, 0 — если нет, и false — если возникает ошибка:
int preg_match (string $pattern, string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]])
Регулярного выражения пример, который возвращает количество найденных совпадений:
int preg_match_all (string $pattern, string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]])
Замена
Выражение возвращает замененную строку или массив (на основе объекта $subject ):
mixed preg_replace (mixed $pattern, mixed $replacement, mixed $subject [, int $limit = -1 [, int $count ]])
Общее использование регулярных выражений в JavaScriptРегулярные выражения в JavaScript выглядят почти так же, как и в PHP .
Сравнение соответствия
Возвращает массив совпадений или null , если совпадений не найдено:
string.match(RegExp);
Замена
Регулярное выражение, которое возвращает строку с выполненными заменами:
string.replace(RegExp, replacement);
Особенности регулярных выражений в JavaScript- Точка никогда не соответствует новой строке:
- Те же методы для сравнения соответствия и замены через регулярное выражение, что и без них.
Рассмотрим пример, в котором нужно найти адреса электронной почты в базе кода. Наша цель:
Аналоговые сокеты
Регулярные выражения состоят из двух типов символов:
- специальные символы: ? * + {} () ^ $ / .
- Литералы.
Представьте себе входные строки как болты, а шаблон — как набор разъемов для них (в соответствующем порядке).
Специальные символы
При проверке регулярных выражений нужно знать, как работают специальные символы:
- Символ обратной косой черты \ может заменять другой специальный символ в регулярном выражении:
- Точка и w — .
Совпадение со всеми символами, кроме новых строк. Если хотите проверить на соответствие точке, и только точке — , на соответствие буквам, цифрам и нижнему подчеркиванию — w
- Квадратные скобки .
Совпадение с символами внутри скобок. Поддерживает диапазоны. Некоторые примеры:
o — соответствует любым a, b или c.
o прописные буквы.
o любая цифра.
o — соответствует любому буквенному символу в нижнем или верхнем регистре.
Опционально? Соответствие 0 или 1.
Звездочка *.
Звездочка обозначает 0 или более символов.
Соответствие 1 или более символам.
Фигурные скобки {}.
Минимальное и максимальное значения. Некоторые примеры синтаксиса регулярных выражений:
o {1,} не менее 1.
o {1,3} от 1 до 3.
o {1,64} от 1 до 64.
Добавим все это, чтобы получить регулярное выражение для адресов электронной почты:
/+@+(.+)*/i
Как это выглядит в PHP :
preg_match_all("/+@+(.+)*/i", $input_lines, $output_array);
Использование регулярного выражения для валидацииЗадача : убедиться, что вводимые данные — это то, что мы ожидаем. Цель 1 : /[^w$.]/ Цель 2: /^{1,2}$/
Регулярные выражения подходят для поиска элементов, но вам нужно знать, что именно вы ищете.
Когда не стоит использовать регулярное выражение для проверки?Многие случаи лучше обрабатывать с помощью функции PHP filter_var . Например, проверка адреса электронной почты должна выполняться с помощью встроенных фильтров PHP :
filter_var("bob@example.com", FILTER_VALIDATE_EMAIL)
Валидация с помощью регулярных выраженийРегулярные выражения в конце строки используют анкоры:
^
— указывает начало строки.
$
— знак доллара, который указывает конец строки.
if (!preg_match("%^{1,2}$%", $_POST["subscription_frequency"])) { $isError = true; }
Исключенные классы символов[^abc] — все, кроме a , b или c , включая новые строки.
Пример, который обеспечивает ввод только буквенно-цифровых символов, тире, точки, подчеркивания:
if (preg_match("/[^0-9a-z-_.]/i", $productCode)) { $isError = true; }
Поиск и заменаНаиболее распространенными функциями PCRE для выполнения поиска и замены являются preg_replace() и preg_replace_callback() . Но есть также preg_filter() и preg_replace_callback_array() , которые делают почти то же самое. Обратите внимание, что функция preg_replace_callback_array() доступна, начиная с PHP7 .
Заменить слова в списке$subject = "I want to eat some apples."; echo preg_replace("/apple|banana|orange/", "fruit", $subject);
Результат
I want to eat some fruits.
Если в регулярном выражении есть подшаблоны (в круглых скобках ), можно заменить $N или N (где N является целым числом > = 1 ), это называется «обратная ссылка».
Перестановка двух чисел$subject = "7/11"; echo preg_replace("/(d+)/(d+)/", "$2/$1", $subject);
Результат
Изменение форматирования даты$subject = "2001-09-11"; echo preg_replace("/(d+)-(d+)-(d+)/", "$3/$2/$1", $subject);
Результат
Простой пример замены URL-адреса в теге$subject = "Please visit https://php.earth/doc for more articles."; echo preg_replace("#(https?://([^s./]+(?:.[^s./]+)*[^s]*))#i", "$2", $subject);
Результат
Please visit php.earth/doc for more articles.
Иногда нужно выполнить сложный поиск и замену, например, при фильтрации/проверке перед заменой. В этой ситуации может пригодиться preg_replace_callback() .
Приведенное в предыдущем примере регулярное выражение может заменить только URL-адреса , начинающиеся с http или https . Но теперь нам также нужно заменить URL-адреса, начинающиеся с www. Кто-то подумает, что можно просто изменить https? : // в подшаблоне. Например, на (?: Https? : // | www . ), Но это не будет работать в большинстве браузеров, потому что они будут интерпретировать www.domain как относительный путь.
Поэтому в конструкторе регулярных выражений перед заменой нужно выполнить некоторые действия, добавив http:// , если URL-адрес начинается с www .
function add_protocol_if_begins_with_www($matches) { $url = strtolower($matches) === "www." ? "http://" . $matches : $matches; return "{$matches}"; } $subject = "Please visit www.php.earth/doc for more articles."; echo preg_replace_callback("#(https?://|www.)([^s./]+(?>.[^s./]+)*[^s]*)#i", "add_protocol_if_begins_with_www", $subject);
Результат
mixed preg_match (string pattern, string subject [, array &matches [, int flags [, int offset]]])Ищет в заданном тексте subject совпадения с шаблоном pattern
В случае, если дополнительный параметр matches указан, он будет заполнен результатами поиска. Элемент $matches будет содержать часть строки, соответствующую вхождению всего шаблона, $matches - часть строки, соответствующую первой подмаске, и так далее.
flags может принимать следующие значения:
PREG_OFFSET_CAPTURE
В случае, если этот флаг указан, для каждой найденной подстроки будет указана ее позиция в исходной строке. Необходимо помнить, что этот флаг меняет формат возвращаемых данных: каждое вхождение возвращается в виде массива, в нулевом элементе которого содержится найденная подстрока, а в первом - смещение. Данный флаг доступен в PHP 4.3.0 и выше.
Дополнительный параметр flags доступен начиная с PHP 4.3.0.
Поиск осуществляется слева направо, с начала строки. Дополнительный параметр offset может быть использован для указания альтернативной начальной позиции для поиска. Дополнительный параметр offset доступен начиная с PHP 4.3.3.
Замечание: Использование параметра offset не эквивалентно замене сопоставляемой строки выражением substr($subject, $offset) при вызове функции preg_match_all() , поскольку шаблон pattern может содержать такие условия как ^ , $ или (? . Сравните:
В то время как этот пример
Функция preg_match() возвращает количество найденных соответствий. Это может быть 0 (совпадения не найдены) и 1, поскольку preg_match() прекращает свою работу после первого найденного совпадения. Если необходимо найти либо сосчитать все совпадения, следует воспользоваться функцией preg_match_all() . Функция preg_match() возвращает FALSE в случае, если во время выполнения возникли какие-либо ошибки.
Подсказка: Не используйте функцию preg_match() , если необходимо проверить наличие подстроки в заданной строке. Используйте для этого strpos() либо strstr() , поскольку они выполнят эту задачу гораздо быстрее.
Пример 2. Поиск слова "web" в тексте
|