Регулярные выражения для чайников php. PHP (регулярное выражение) - что это такое? Примеры и проверка регулярных выражений

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" в тексте

/*
Специальная последовательность \b в шаблоне означает границу слова,
следовательно, только изолированное вхождение слова "web" будет соответствовать
маске, в отличие от "webbing" или "cobweb".
*/
if (preg_match ("/\bweb\b/i" , "PHP is the web scripting language of choice." )) {
echo "Вхождение найдено." ;
} else {
echo "Вхождение не найдено." ;
}preg_match ("/\bweb\b/i" , "PHP is the website scripting language of choice." )) {
echo "Вхождение найдено." ;
} else {
echo "Вхождение не найдено." ;
}
?>

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

Бурное развитие Интернета и языков WEB-разработки потребовало создания универсальных и компактных средств обработки текстовой информации при минимальном количестве требуемого для этого кода. Не является исключением и популярный среди начинающих и профессиональных разработчиков язык PHP. Регулярное выражение как язык текстовых шаблонов позволяет упростить задачи обработки текста и уменьшить программный код на десятки и сотни строк. Многие задачи вообще невозможно решить без него.

Регулярные выражения в PHP

Язык PHP содержит три механизма работы с регулярными выражениями - «ereg», «mb_ereg» и «preg». Наиболее распространенным является интерфейс «preg», функции которого обеспечивают доступ к библиотеке поддержки регулярных выражений PCRE, изначально разработанной для языка Perl, которая входит в комплект PHP. Preg-функции ищут в заданной текстовой строке совпадения, согласно определенному шаблону на языке регулярных выражений.

Основы синтаксиса

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

В формально определяется очень сложно, и поэтому упростим описание. Регулярное выражение представляет собой текстовую строку. Она состоит из выделенного разделителем шаблона и модификатора, указывающего на то, каким образом его обрабатывать. Возможно включение в шаблоны различных альтернатив и повторений.

Например, в выражении /\d{3}-\d{2}-\d{2}/m разделителем будет «/» , далее идет шаблон, а символ «m» будет модификатором.

Вся мощь регулярных выражений кодируется с помощью метасимволов. Основным метасимволом языка является обратный слэш - «\». Он меняет тип следующего за ним символа на противоположный (т. е. обычный символ превращается в метасимвол и наоборот). Другим важным метасимволом является прямая черта «|», задающая альтернативные варианты шаблона. Еще примеры метасимволов:

PHP, обрабатывая регулярные выражения, пробел рассматривает как отдельный значимый символ, поэтому выражения АБВГДЕ и АБВ ГДЕ являются разными.

Подшаблоны

В PHP регулярные подшаблоны выделяются круглыми скобками и иногда называются «подвыражениями». Выполняют следующие функции:

    Выделение альтернатив . Например, шаблон жар(кое|птица|) совпадет со словами «жар», «жар-птица» и «жаркое» . А без скобок это будет только пустая строка, «птица» и «жаркое».

    «Захватывающий» подшаблон. Это означает, что если в шаблоне совпала подстрока, то в качестве результата возвращаются все совпадения. Для наглядности приведем пример. Дано следующее регулярное выражение: победитель получает((золотую|позолоченный)(медаль|кубок)) - и строка для поиска совпадений: «победитель получает золотую медаль» . Кроме исходной фразы, в результате поиска будут выданы: «золотую медаль» , «медаль», «золотую» .

Операторы повторений (квадрификаторы)

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

Для описания повторений применяются квадрификаторы - метасимволы для задания количества. Квадрификаторы бывают двух типов:

  • общие, заключенные в скобки;
  • сокращенные.

Общий квантификатор задет минимальное и максимальное количество разрешенных повторений элемента в виде двух чисел в фигурных скобках, например так: х{2,5}. Если максимальное количество повторений неизвестно, второй аргумент не указывается: х{2,}.

Сокращенные квантификаторы представляют собой символы для наиболее распространенных повторений во избежание лишней перегрузки синтаксиса. Обычно используются три сокращения:

1. * - ноль и больше повторений, что эквивалентно {0,}.

2. + - одно и более повторений, т. ,}.

3. ? - ноль или только одно повторение - {0,1}.

Примеры регулярных выражений

Для тех, кто изучает регулярные выражения, примеры - лучший учебник. Мы приведем несколько, которые показывают их широкие возможности при минимуме усилий. Все программные коды полностью совместимы с версиями PHP 4.x и выше. Для полного понимания синтаксиса и использования всех возможностей языка рекомендуем книгу Дж. Фридла «Регулярные выражения», где полностью рассматривается синтаксис и имеются примеры регулярных выражений не только на PHP, но и для языков Python, Perl, MySQL, Java, Ruby и C#.

Проверка корректности адреса E-mail

Задача. Существует Интернет-страница, на которой у посетителя запрашивается адрес email. Регулярное выражение должно проверять правильность полученного адреса перед отправкой сообщений. Проверка не дает гарантии, что указанный почтовый ящик реально существует и принимает письма. Но отсеять заведомо неправильные адреса она может.

Решение. Как и в любом языке программирования, на PHP регулярные выражения email-проверки адреса могут быть реализованы разными способами, и примеры в этой статье не являются окончательным и единственным вариантом. Поэтому в каждом случае мы будем приводить перечень требований, которые нужно учесть при программировании, а конкретная реализация полностью зависит от разработчика.

Итак, выражение, проверяющее правильность email, должно проверять следующие условия:

  1. Наличие в исходной строке символа @ и отсутствие пробелов.
  2. Доменная часть адреса, за символом @, содержит только допустимые символы для доменных имен. То же относится и к имени пользователя.
  3. При проверке имени пользователя необходимо определить наличие специальных символов, таких как апостроф или Такие символы относятся к потенциально опасным и могут содержаться в таких видах нападений, как SQL-инъекции. Избегайте таких адресов.
  4. Имена пользователя допускают наличие только одной точки, которая не может быть первым или последним символом в строке.
  5. Доменное имя должно содержать не меньше двух и не более шести символов.

Пример, учитывающий все указанные условия, можно увидеть далее на рисунке.

Проверка правильности адресов URL

Задача. Проверить, является ли заданная текстовая строка допустимым Еще раз отметим, что регулярные выражения URL-проверки могут быть реализованы различными способами.

Решение. Наш итоговый вариант выглядит следующим образом:

/^(https?:\/\/)?([\da-z\.-]+)\.({2,6})([\/\w \.-]*)*\/?$/

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

Проверяем номера кредитных карт

Задача. Необходимо реализовать проверку правильности введенного номера пластиковой карты наиболее распространенных платежных систем. Рассмотрен вариант только для карт

Решение. При создании выражения необходимо учитывать возможное наличие во введенном номере пробелов. Цифры номера на карте разделены на группы для упрощения чтения и диктовки. Поэтому вполне естественно, что человек может попытаться ввести номер таким образом (т. е. используя пробелы).

Написать универсальное выражение, учитывающее возможные пробелы и дефисы, сложнее, чем просто отбросить все символы, кроме цифр. Поэтому в выражении рекомендуется использовать метасимвол /D, который удаляет все символы, кроме цифр.

Теперь можно переходить непосредственно к проверке номера. Все компании, выпускающие кредитные карты, используют уникальный формат номера. В примере это используется, и клиенту нет необходимости вводить наименование компании - она определяется по номеру. Карты Visa всегда начинаются с 4 и имеют длину номера в 13 или 16 цифр. MasterCard начинается в диапазоне 51-55 с длиной номера 16. В итоге получаем такое выражение:

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

Проверка телефонных номеров

Задача. Проверка корректности введенного телефонного номера.

Решение. Количество цифр в стационарных и мобильных телефонных номерах значительно различается в зависимости от страны, поэтому универсально проверить, используя регулярные выражения, номер телефона на правильность невозможно. Но международные номера имеют строгий формат и отлично подходят для проверки по шаблону. Тем более что все больше национальных телефонных операторов стараются соответствовать единому стандарту. Структура номера следующая:

+CCC.NNNNNNNNNNxEEEE, где:

C - это код страны, состоящий из 1-3 цифр.

N - номер длиной до 14 цифры.

E - необязательное расширение.

Плюс является обязательным элементом, а знак х присутствует только при необходимости расширения.

В результате имеем следующее выражение:

^\+{1,3}\.{4,14}(?:x.+)?$

Числа в диапазоне

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

Решение. Приведем несколько выражений для нескольких наиболее распространенных случаев:

Поиск IP-адреса

Задача. Необходимо определить, является ли заданная строка допустимым IP-адресом в формате IPv4 в диапазоне от 000.000.000.000-255.255.255.255.

Решение. Как и в любой задаче на языке PHP, регулярное выражение имеет множество варинтов. Например, такое:

Онлайн-проверка выражений

Проверка регулярных выражений на правильность для начинающих программистов может быть затруднительной из-за сложности синтаксиса, отличающегося от «обычных» языков программирования. Для решения данной проблемы существует множество онлайн-тестеров выражений, позволяющих легко проверить правильность созданного шаблона на реальном тексте. Программист вводит выражение и данные для проверки и мгновенно видит результат обработки. Обычно здесь же присутствует справочный раздел, где подробно описываются регулярные выражения, примеры и отличия реализации для наиболее распостраненных языков программирования.

Но полностью доверять результатам онлайн-сервисов не рекомендуется всем разработчикам, пользующимся PHP. Регулярное выражение, написанное и проверенное лично, повышает квалификацию и гарантирует отсутствие ошибок.

Давайте начнем с того, что такое регулярное выражение. Вот ответьте мне на вопрос, есть ли в слове "test" буква "e"? "Есть!" скажете Вы. Тогда я задаю Вам второй вопрос, как вы нашли букву "e" в слове "test"? Ответ очевиден, берем первый символ, то есть "t" сравниваем его с тем что ищем, то есть с "e". Если они не равны, то берем второй символ, то есть "e", сравниваем его с тем что ищем, то есть "e". Вуаля! Найдено совпадение. Ответ: В слове "test" есть буква "e" .

А теперь ответьте мне на еще один вопрос, где в этом примере регулярное выражение? Надеюсь Вы догадались, что регулярным выражением тут является то, что мы ищем в слове "test". То есть буква "e" в данном примере и есть регулярное выражение.

Для чего используют регулярные выражения в php? В моей практике регулярные выражения использовались, например, для определение корректно ли составлен адрес электронной почты. Так же такие выражения используют для определения корректности имя пользователя и пароля. С помощью регулярных выражений можно найти в ссылке адрес и сохранить его. Много чего можно делать Проанализировав это можно выявить главную функцию регулярных выражений, и две побочных. Главная функция , это поиск совпадений в строке. Побочные же - это сохранения найденных совпадений, и замена.

Первое регулярное выражение

В теории мы понимаем как найти символ "e" в слове "test", как же это реализуется на практике? Для использования регулярных выражений в php обычно используют функции:

preg_match("регулярное выражение (шаблон)", "переменная в которое производится поиск", "Переменная в которое сохраняется результат поиска (не обязательный параметр)"); - Функция поиска соответствий
preg_replace("регулярное выражение (шаблон)", "На что заменить найденное совпадение", "переменная в которое производится замена"); - Функция замены

Начнем же использовать эти функции.. Вот пример поиска символа "e" в слове "test":

$a = "test";
if(preg_match("/e/",$a)) echo "найдено!!";

В коде описано условие, если в переменной $a найдено что-то по шаблону, то выдать сообщение "найдено!!" Как Вы могли заметить наш шаблон стоит между двумя "/". В данном случае символ "/" символизирует начало и конец нашего шаблона . Надеюсь это понятно.

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

Как найти эту букву? Там может быть любая буква английского алфавита, как же ее определить? Вы сами ответили на свой вопрос, там любая буква, то есть она находится в диапазоне от a до z. В регулярных выражениях можно использовать диапазоны. Если мы не знаем какой символ ищем, но точно знаем что этот символ является буквой английского алфавита, то запись будет следующая:

$a = "123a321";
if(preg_match("//",$a)) echo "найдено!!";

Заметьте, что диапазон ставится в "[" "]" скобках. Все что заключено в такие скобки определяется как один символ, в данном случае символ варьируется в диапазоне от a до z. Если же нам понадобится найти не букву, а цифру, то запись будет такая:

$a = "abc1cba";
if(preg_match("//",$a)) echo "найдено!!";

Так же хочу заметить, что регулярные выражение чувствительны к регистру, поэтому символы "A" и "a" совершенно разные, для поиска тех и тех символов, пишут так:

$a = "123a321";
if(preg_match("//",$a)) echo "найдено!!";

Так же существует поиск русских букв, осуществляется так же как и с английскими:

$a = "123ы321";
if(preg_match("/[а-яА-Я]/",$a)) echo "найдено!!";

Метасимволы

Мы научились искать неизвестный символ в строке. Что же делать если нам необходимо найти несколько символов? На помощь приходят так называемые метасимволы... Предположим у нас есть строка с циферками, буковками, как ее описать в шаблоне? Можно так:

строка - 123а321
шаблон -

Хм... шаблон и вправду подходит к нашей строке, и при проверки на соответствие даст долгожданное true! Но какая то громоздкая запись, Вам не кажется?

Вот как ее можно сократить:

строка - 123а321
шаблон - *

Мне кажется так покороче Что же из себя представляет символ "*"? Это и есть тот самый метасимвол, он означает что описанный нами символ (а именно символ который может содержать цифры от 0 до 9 или буквы английского алфавита, от a до z) может повторяться до бесконечности раз, или же не одного раза. Да да! Этот метасимвол, найдет совпадение в пустой переменной, так как даже отсутствие описанного нами символа выдаст true! Запомните это

Какие еще бывают метасимволы?

Например метасимвол "+" Он почти что схож с метасимволом "*" за одним маленьким исключением. "*" выдаст true даже при отсутствия символа, а "+" проверит на наличие хотя бы одного символа. То есть если в строке необходимо наличие минимум одного символа то используйте "+" вместо "*"

Так же часто используют метасимвол "?" Он означает что в строке должно находится не более одного искомого символа. Давайте я приведу пару примеров для двух последних, описанных мной метасимволов.

Предположим нам необходимо проверить на корректность пароль пользователя. Давайте подумаем что должен содержать пароль пользователя? Ну во-первых он должен быть не меньше одного символа. Во-вторых он должен содержать только цифры и буквы английского алфавита, стало быть регулярное выражение будет выглядеть вот так:

$a = "qwerty12345";

Какие символы мы разрешили? Английские буквы любого регистра и цифры. Теперь попробуйте вместо пароля оставить пустую строчку.

$a = "";
if(preg_match("/+/",$a)) echo "Пароль верный";

Вам не высветится сообщение "Пароль верный". Почему? Потому что метасимвол "+" проверил строку на наличие хотя бы одного символа.

А теперь небольшой фокус, давайте взглянем на наше выражение, мы ведь не разрешали в нем, ну скажем пробел, ведь так? поставьте пробел в конце пароля и запустите

$a = "qwerty12345 ";
if(preg_match("/+/",$a)) echo "Пароль верный";

И почему мы видим наше сообщение о корректном пароле? Все довольно просто... Функция preg_match(); останавливает свою проверку при первом же совпадение. То есть символ "q" подходит под описанный нами шаблон, а все остальное для функции уже не важно Что же делать? Вот как это исправить:

$a = "qwerty12345 ";
if(preg_match("/^+$/",$a)) echo "Пароль верный";

Добавляя "^" в начале выражения и "$" в конце, мы говорим функции, что шаблону должна соответствовать вся строка. Если вы запустите этот код, то сообщения не увидите, так как в конце пароля стоит недопустимый символ - пробел

Теперь смените метасимвол "+" на метасимвол "?". Как Вы думаете что произойдет? Правильно сообщение о корректности пароля будет отсутствовать, так как в пароле более одного символа. Надеюсь я нормально объяснил работу, этих трех, часто используемых, метасимволов

Иногда "не" лучше

Мы как минимум научились проверять правильность пароля, и это хорошо! Давайте я Вам расскажу про еще одни способ поиска чего либо в строке. Вот скажем нам нужно проверить отсутствие в строке цифр. Как это сделать? Вот строка:

(Я специально ввел в нее эти "-_+()" символы что бы жизнь медом не казалась... ) Мы могли бы составить следующее выражение:

Но согласитесь, ведь мы не всегда знаем какие символы используются в строке, но нам точно известно, что цифр в ней быть не должно! Стало быть логичнее было бы просто написать шаблон, который пропускал бы строки в которых нет цифр, а не те, в которых присутствует "О боже мой сколько же не понятных символов!!!" . Вот пример правильно составленного выражения для таких задач:

$a = "a-_+()";
if(preg_match("/^[^0-9]+$/",$a)) echo "Цифр нет!";

Как же мы этого добились? Мы ввели символ , но! поставленная в начале крышка "^" ([^0-9]) говорит о том, что в строке этого символа быть не должно Надеюсь с этим разобрались

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

Увидел, сохранил!

Мой блог

$a = "Мой блог";
preg_match("//", $a);

В нашем регулярном выражение мы описали все возможные символы которые могут входить в ссылку. Так же хочу обратить внимание на символы кавычки и "/" в нашем выражение.. Перед ними стоит обратный слеш, для чего он? Дело в том что "/" и кавычка сами по себе спецсимволы. И для того что бы шаблон их воспринял как обычные символы, нам необходимо их экранизировать. Экранизация проводится путем добавление перед спецсимволами обратный слеш. Надеюсь понятно

$a = "Мой блог";
preg_match("//", $a, $b);

Ну и соответственно необходимо дописать дополнительный параметр в виде переменной $b, в ней и будет храниться найденная ссылка. Так же необходимо знать, что результат поиска помещается в массив. Стало быть переменная $b - массив. Искомая нами информация находится под индексом 1. А это означает, что результат поиска в переменной $b. выведем результат на экран:

$a = "Мой блог";
preg_match("//", $a, $b);
echo $b;

Правильный адрес, залог успеха!

Ну и на по следок, ответ на вопрос, корректный ли e-mail? Для начала, необходимо узнать, какие символы разрешены в адресах? Насколько мне известно в разрешенные символы входят:

  • английские буквы, цифры, "_", "-" эмммм вроде все... Будем исходить их этого.
  • Дальше у нас идет "@"
  • После, английские буквы
  • Далее, точка
  • И опять английские буквы...

Стало быть регулярное выражение будет следующим:

$a = "[email protected]";
if(preg_match("/^+@+.+$/", $a)) echo "e-mail адрес составлен корректно!";
else echo "e-mail адрес составлен НЕ корректно!";

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

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

Что касается цикла статей о разработке cms блога , первую часть цикла оглашаю закрытой! В скором будущем мы начнем реализовывать админ панель, так что не "переключайтесь" Если у Вас есть какие то вопросы, с удовольствием отвечу. Всего Вам самого наилучшего, у меня все!