W3docs

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

Регулярные выражения в PHP: синтаксис паттернов, функции preg_, валидация, поиск и замена текста с примерами кода.

Регулярное выражение (regex) — это паттерн, описывающий набор строк. Вместо поиска одного фиксированного фрагмента текста вы описываете его форму — «адрес электронной почты», «последовательность цифр», «слово, заканчивающееся на .php» — и PHP находит, проверяет, заменяет или разбивает текст, соответствующий этому паттерну.

В этой главе рассматривается, как работают функции preg_ в PHP, синтаксис паттерна (разделители, классы символов, кванторы, группы, якоря), а также наиболее частые практические задачи: валидация ввода, извлечение данных и замена текста.

Что такое регулярные выражения

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

ТокенЗначениеПример совпадения
.Любой одиночный символ (кроме новой строки)c.tcat, cut
\dЦифра 0-9\d\d42
\w«Словесный» символ (a-z, A-Z, 0-9, _)\w+hello_1
\sПробельный символ (пробел, табуляция, новая строка)
[abc]Любой из символов a, b, c[aeiou]e
[^abc]Любой символ кроме a, b, c
a*Ноль или более a"", aaa
a+Один или более aa, aaa
a?Ноль или один a (необязательный)"", a
a{2,4}От 2 до 4 символов aaa, aaaa
^ / $Начало / конец строки
|Альтернатива («или»)cat|dogcat или dog
()Группировка / захват(ab)+abab

Как работают регулярные выражения в PHP

PHP использует PCRE (Perl-Compatible Regular Expressions) через семейство функций preg_. Наиболее часто используемые:

ФункцияЧто делает
preg_match()Проверяет совпадение паттерна; захватывает первое совпадение
preg_match_all()Находит все совпадения в строке
preg_replace()Заменяет каждое совпадение новым текстом
preg_split()Разбивает строку по паттерну
preg_quote()Экранирует метасимволы regex в литеральной строке

Синтаксис паттерна в PHP

Паттерн в PHP — это строка, состоящая из трёх частей: разделителя, паттерна и необязательных модификаторов.

/pattern/modifiers

Первый символ — это разделитель — почти всегда /, но подойдёт любой неалфавитно-цифровой символ (#, ~, !). Выбор разделителя, который не встречается в вашем паттерне, избавляет от необходимости экранирования. Например, при совпадении URL-пути удобнее использовать #:

"#^/users/\d+$#"   // no need to escape the slashes

modifiers — это необязательные буквы после закрывающего разделителя, изменяющие поведение движка:

  • i — без учёта регистра: /php/i совпадает с PHP, Php, php.
  • mмногострочный режим: ^ и $ совпадают с началом/концом каждой строки, а не всей строки целиком.
  • sодинарная строка («dotall»): . также совпадает с символами новой строки.
  • u — обрабатывать паттерн и строку как UTF-8. Используйте для любого текста с не-ASCII символами.
  • x — расширенный режим: пробелы в паттерне игнорируются, что позволяет разбивать и комментировать сложные паттерны.

Проверка совпадения с помощью preg_match

preg_match() возвращает 1, если паттерн найден, 0 — если нет, и false при ошибке. Это правильный выбор для вопросов «да/нет», например: «содержит ли эта строка цифру?»

php— editable, runs on the server

Необязательный третий аргумент $matches заполняется результатами: $matches[0] — это полное совпадение, а $matches[1], $matches[2], … — это захватывающие группы в порядке их появления — подстроки, захваченные каждой парой скобок.

Валидация пользовательского ввода

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

<?php

$email = "[email protected]";

if (preg_match("/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/", $email)) {
    echo "Valid email address";
} else {
    echo "Invalid email address";
}

?>

Якоря ^ и $ здесь важны: без них паттерн совпадал бы с адресом электронной почты внутри более длинной строки, и "junk [email protected] junk" прошёл бы проверку. С якорями вся строка должна представлять собой единственный адрес электронной почты.

Для проверки email в частности встроенная функция PHP filter_var() с FILTER_VALIDATE_EMAIL надёжнее, чем написанный вручную regex. Обращайтесь к regex, когда вам нужен формат, который не поддерживают фильтры, — почтовые индексы, пользовательские идентификаторы, форматы телефонов. Полный пример проверки ввода см. в разделе Валидация форм в PHP.

Поиск всех совпадений с помощью preg_match_all

Там, где preg_match() останавливается на первом совпадении, preg_match_all() собирает все — это удобно для извлечения каждого хэштега, цены или ссылки из блока текста.

<?php

$text = "Prices: $12, $7 and $349";

preg_match_all("/\\\$(\d+)/", $text, $matches);

print_r($matches[1]); // the captured numbers

?>

$matches[1] содержит массив всех захваченных групп — в данном случае ["12", "7", "349"].

Замена текста с помощью preg_replace

preg_replace() заменяет каждое совпадение. В строке замены $1, $2, … ссылаются на захваченные группы, поэтому вы можете не только удалять, но и переписывать:

<?php

$date = "2026-06-21";

// Reformat YYYY-MM-DD into DD/MM/YYYY
echo preg_replace("/(\d{4})-(\d{2})-(\d{2})/", "$3/$2/$1", $date);
// 21/06/2026

?>

Чтобы разбить строку на части по паттерну вместо замены, используйте preg_split() — например, разбиение по любому количеству пробелов с помощью /\s+/.

Продвинутые техники

Освоив основы, вы сможете использовать следующие возможности для работы с более сложными паттернами:

  • Захватывающие группы (...) — извлекают конкретные части совпадения, как показано выше с $matches[1].
  • Незахватывающие группы (?:...) — группируют без занятия слота $matches, когда группировка нужна только для квантора или альтернативы.
  • Именованные группы (?<year>\d{4}) — ссылка на совпадение по имени ($matches['year']) вместо номера.
  • Предпросмотр вперёд (?=...) и предпросмотр назад (?<=...) — совпадение на основе того, что идёт после или перед, без его потребления. Полезно для «числа, за которым следует px», без захвата px.
  • Ленивые кванторы *?, +? — совпадение с минимально возможным числом символов. По умолчанию .* является жадным и захватывает всё возможное.

Замечание об экранировании: символы вроде ., +, *, ?, (, ), [, \ имеют особое значение. Чтобы совпасть с ними буквально, добавьте обратный слэш (\. совпадает с буквальной точкой). Когда литеральный текст берётся из переменной, используйте preg_quote() для его безопасного экранирования.

Частые ошибки

  • Забытые разделители. Паттерны в PHP являются строками и должны включать разделители: "/\d+/", а не "\d+". Их отсутствие вызывает предупреждение, и совпадение не находится.
  • Двойное экранирование в строках с двойными кавычками. Внутри "..." обратный слэш также является PHP-экранирующим символом. "/\d/" работает, потому что \d не является PHP-последовательностью экранирования, но для совпадения с буквальным $ нужно написать "/\\$/". Строки с одинарными кавычками ('/\d/') избавляют от этого сюрприза.
  • Жадное совпадение захватывает слишком много. <.*> на <a><b> совпадает со всей строкой <a><b>, а не только с <a>. Используйте ленивое <.*?> или отрицательный класс <[^>]*>.
  • Пропуск модификатора u для UTF-8. Без /u . и \w работают на уровне байтов, искажая многобайтовые символы.

Заключение

Регулярные выражения позволяют описывать форму текста, а не его точное содержимое, что делает их незаменимыми для валидации ввода, извлечения данных и преобразования строк. В PHP для их использования применяются функции preg_: preg_match() и preg_match_all() для поиска, preg_replace() для перезаписи и preg_split() для разбивки строк. Начните с якорей, классов символов и кванторов, затем добавляйте группы и предпросмотр по мере усложнения паттернов. Чтобы узнать больше о строках, с которыми вы будете работать, см. PHP Строки.

Практика

Практика
В чём основное назначение регулярных выражений в PHP?
В чём основное назначение регулярных выражений в PHP?
Was this page helpful?