Регулярные выражения в англоязычной практике часто называются regex
или RegExp
и представляют собой текстовые строки в специальном формате, используемые для поиска шаблонов в тексте. Регулярные выражения — один из самых мощных инструментов, доступных сегодня для эффективной обработки текста и манипуляций с ним.
Например, его можно использовать для проверки правильности формата данных — имени, адреса электронной почты, номера телефона, поиска или замены совпадающих строк в текстовом содержимом и т. д.
PHP (версия 5.3+) поддерживает регулярные выражения в синтаксисе Perl. Perl (Practical Extraction and Report Language) был первым распространенным языком программирования, который обеспечивал интегрированную поддержку регулярных выражений и большие возможности обработки и манипулирования текстом.
Давайте начнем с краткого обзора часто используемых встроенных функций сопоставления с образцом в PHP.
Функция | Что делает |
---|---|
preg_match() |
Выполняет сопоставление регулярного выражения. |
preg_match_all() |
Выполняет глобальное сопоставление регулярного выражения. |
preg_replace() |
Выполняет поиск и замену по регулярному выражению. |
preg_grep() |
Возвращает элементы входного массива, соответствующие шаблону. |
preg_split() |
Разбивает строку на подстроки с помощью регулярного выражения. |
preg_quote() |
Цитирует символы регулярного выражения, найденные в строке. |
PHP-функция preg_match()
прекращает поиск после нахождения первого совпадения, тогда как функция preg_match_all()
продолжает поиск до конца строки и находит все возможные совпадения вместо остановки на первом совпадении.
Синтаксис регулярных выражений
Синтаксис регулярных выражений включает использование специальных символов (не путать со специальными символами HTML). В регулярном выражении особое значение имеют следующие символы: .
*
?
+
[
]
(
)
{
}
^
$
|
\
. Вам нужно будет использовать обратную косую черту (слеш) для этих символов всякий раз, когда вы захотите использовать их буквально. Например, если вы хотите использовать в регулярном выражении символ .
вам нужно будет писать \.
. Все остальные символы автоматически принимают свои буквальные значения.
В следующих разделах описаны различные варианты, доступные для формулирования шаблонов.
Классы символов
Квадратные скобки, окружающие набор символов, называются классом символов, например [abc]
. Класс символов всегда соответствует одному символу из списка указанных символов, что означает, что выражение [abc]
соответствует только символу a, b или c.
Также могут быть определены классы отрицательных символов, соответствующие любому символу, кроме символов, содержащихся в скобках. Класс инвертируемых символов определяется помещением символа каретки (^
) сразу после открывающей скобки, как, например [^abc]
.
Вы также можете определить диапазон символов, используя символ дефиса (-
) внутри класса символов, например [0-9]
. Давайте посмотрим на несколько примеров этих классов:
RegExp | Что делает |
---|---|
[abc] |
Соответствует любому из символов a, b или c. |
[^abc] |
Соответствует любому символу, кроме a, b или c. |
[a-z] |
Соответствует любому символу от строчного a до строчного z. |
[A-Z] |
Соответствует любому символу от верхнего регистра A до верхнего регистра Z. |
[a-Z] |
Соответствует любому символу от нижнего a до верхнего Z. |
[0-9] |
Соответствует одной цифре от 0 до 9. |
[a-z0-9] |
Соответствует одиночному символу между a и z или между 0 и 9. |
В следующем примере показано, как определить, существует ли шаблон в строке или нет, используя регулярное выражение и PHP-функцию preg_match()
:
<?php
$pattern = "/ca[kf]e/";
$text = "He was eating cake in the cafe.";
if(preg_match($pattern, $text)){
echo "Match found!";
} else{
echo "Match not found.";
}
?>
Точно так же вы можете использовать функцию preg_match_all()
, чтобы найти все совпадения в строке:
<?php
$pattern = "/ca[kf]e/";
$text = "He was eating cake in the cafe.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " matches were found.";
?>
Регулярные выражения не являются уникальными для PHP. Такие языки, как Java, Perl, Python и т. д., используют ту же нотацию для поиска шаблонов в тексте.
Предопределенные классы символов
Некоторые классы символов, такие как цифры, буквы и пробелы, используются так часто, что для них есть предопределенные ярлыки. В следующей таблице перечислены эти предопределенные классы символов:
Shortcut | Что делает |
---|---|
. |
Соответствует любому одиночному символу, кроме новой строки \n . |
\d |
Соответствует любому цифровому символу. Тоже, что и [0-9] |
\D |
Соответствует любому нецифровому символу. Тоже, что и [^0-9] |
\s |
Соответствует любому пробельному символу (пробел, табуляция, новая строка или символ возврата каретки). Тоже, что и [ \t\n\r] |
\S |
Соответствует любому непробельному символу. Тоже, что и [^ \t\n\r] |
\w |
Соответствует любому буквенному символу (определяется как от a до z, от A до Z, от 0 до 9 и подчеркивание). Тоже, что и [a-zA-Z_0-9] |
\W |
Соответствует любому не буквенному символу. Тоже, что и [^a-zA-Z_0-9] |
В следующем примере показано, как найти и заменить пробел символом дефиса в строке с помощью регулярного выражения и PHP-функции preg_replace()
:
<?php
$pattern = "/\s/";
$replacement = "-";
$text = "Earth revolves around\nthe\tSun";
// Заменяем пробелы, символы новой строки и табуляции
echo preg_replace($pattern, $replacement, $text);
echo "<br>";
// Заменяем только пробелы
echo str_replace(" ", "-", $text);
?>
Количественные повторители (квантификаторы)
В предыдущем разделе мы узнали, как сопоставлять сиволы разными способами. Но что, если вы хотите сопоставить более одного символа? Например, предположим, что вы хотите найти слова, содержащие один или несколько экземпляров буквы p
, или слова, содержащие как минимум две буквы p
, и так далее. Здесь вам помогут квантификаторы. С помощью квантификаторов вы можете указать, сколько раз должен совпадать символ в регулярном выражении.
В следующей таблице перечислены различные способы количественной оценки конкретного паттерна:
RegExp | Что делает |
---|---|
p+ |
Соответствует одному или нескольким вхождениям буквы p. |
p* |
Соответствует нулю или более вхождений буквы p. |
p? |
Соответствует нулю или одному появлению буквы p. |
p{2} |
Соответствует ровно двум вхождениям буквы p. |
p{2,3} |
Соответствует как минимум двум, но не более трем появленям буквы p. |
p{2,} |
Соответствует двум или более вхождениям буквы p. |
p{,3} |
Соответствует не более чем трем появлениям буквы p |
Регулярное выражение в следующем примере разбивает строку на запятую, последовательность запятых, пробелы или их комбинацию с помощью PHP-функции preg_split()
:
<?php
$pattern = "/[\s,]+/";
$text = "My favourite colors are red, green and blue";
$parts = preg_split($pattern, $text);
// Перебираем массив частей и отображать подстроки
foreach($parts as $part){
echo $part . "<br>";
}
?>
Начало и конец строки (якоря)
Есть определенные ситуации, когда вы захотите сопоставить начало или конец слова или строки. Для этого можно использовать два якоря — это каретка (^
), обозначающая начало строки, и знак доллара ($
), обозначающий конец строки.
RegExp | Что делает |
---|---|
^p |
Соответствует букве p в начале строки. |
p$ |
Соответствует букве p в конце строки. |
Регулярное выражение в следующем примере будет отображать только те имена из массива names, которые начинаются с буквы «J» с использованием PHP-функции preg_grep()
:
<?php
$pattern = "/^J/";
$names = array("Jhon Carter", "Clark Kent", "John Rambo");
$matches = preg_grep($pattern, $names);
// Перебираем массив и отображаем совпадающие имена
foreach($matches as $match){
echo $match . "<br>";
}
?>
Модификаторы (флаги)
Модификатор шаблона позволяет вам контролировать способ обработки соответствия шаблону. Модификаторы размещаются непосредственно после регулярного выражения, например, если вы хотите искать шаблон без учета регистра, вы можете использовать модификатор i
, например: /pattern/i
.
В следующей таблице перечислены некоторые из наиболее часто используемых модификаторов шаблона.
Модификатор | Что делает |
---|---|
i |
Делает совпадение нечувствительным к регистру. |
m |
Изменяет поведение ^ и $ для соответствия границе новой строки (т. е. начало или конец каждой строки в многострочной строке) вместо границы строки. |
g |
Выполняет глобальное сопоставление, т.е. ищет все вхождения. |
o |
Оценивает выражение только один раз. |
s |
Изменяет поведение . (точка) для соответствия всем символам, включая символы новой строки. |
x |
Позволяет использовать пробелы и комментарии в регулярном выражении для ясности. |
В следующем примере показано, как выполнить глобальный поиск без учета регистра с использованием модификатора i
и PHP-функции preg_match_all()
.
<?php
$pattern = "/color/i";
$text = "Color red is more visible than color blue in daylight.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " matches were found.";
?>
Точно так же в следующем примере показано, как сопоставить начало каждой строки в многострочной строке с помощью привязки ^
и модификатора m
с PHP-функцией preg_match_all()
.
<?php
$pattern = "/^color/im";
$text = "Color red is more visible than \ncolor blue in daylight.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " matches were found.";
?>
Границы слов
Символ границы слова (\b
) помогает вам искать слова, которые начинаются и/или заканчиваются определенным шаблоном. Например, регулярное выражение /\bcar/
соответствует словам, начинающимся с шаблона car
, и будет соответствовать cart
, carrot
, или cartoon
, но не будет совпадать с oscar
.
Аналогично, регулярное выражение /car\b/
соответствует словам, оканчивающимся шаблоном car
, и будет соответствовать oscar
или supercar
, но не будет соответствовать cart
. Аналогично, /\bcar\b/
соответствует словам, начинающимся и заканчивающимся шаблоном car
и будет соответствовать только слову car
.
Следующий пример выделит слова, начинающиеся с car
жирным шрифтом:
<?php
$pattern = '/\bcar\w*/';
$replacement = '<b>$0</b>';
$text = 'Words begining with car: cart, carrot, cartoon. Words ending with car: scar, oscar, supercar.';
echo preg_replace($pattern, $replacement, $text);
?>
О регулярных выражениях в JavaScript см. Руководство по регулярным выражениям в JavaScript.
Чтобы узнать, как проверять данные формы с помощью регулярных выражений, см. Руководство по валидации форм в PHP.