Регулярные выражения в PHP
Кратко:
^ Начало регулярного выражения
$ Конец регулярного выражения
\A Начало строки
\z Конец строки
. Один любой символ
\s Один пустой символ (пробел, таб, символ перевода строки)
\S Любой непустой символ
\d Любая цифра
\D Любая не цифра
\w Любая буква и нижнее подчёркивание
\W Не буква и не нижнее подчёркивание
\b Граница слова (\bHello\b - совпадение с 'Hello')
(...) Подвыражение (Subpattern)
(a|b) a или b
? Ноль или одно повторение чего-либо
* Ноль и более
+ Один и более
{3} 3 повторения
{3,} 3 и более повторения
{3,6} 3-6 повторений
Ограничители (Delimiters)
При использовании PCRE (Perl Compatible Regular Expressions) в функциях, необходимо чтобы выражение было заключено в ограничители. Ими могут быть любые небуквенно-цифровые символы, не обратные слэши и не пустые символы (whitespace). Наиболее часто в качестве ограничителей используют прямой слэш '/', знак хэша '#' или тильду '~'. Например:
/foo bar/ #^[^0-9]$# +php+ %[a-zA-Z0-9_-]%
Если необходимо использовать символ ограничителя в выражении, он должен быть экранирован обратным слэшем:
'/http:\/\//' '#http://#'
Функция preg_quote() может быть использована чтобы экранировать строку для внедрения её в выражение. Можно использовать второй необязательный параметр для экранирования конкретного символа:
<?php $keywords = '$40 for a g3/400'; $keywords = preg_quote($keywords, '/'); echo $keywords; // returns \$40 for a g3\/400 ?>
После ограничителей можно использовать модификаторы выражения. Например, данный модификатор укажет, что данное выражение регистронезависимое:
/[a-z]/i
PCRE спецсимволы:
Любые из этих символов при использовании в регулярных выражениях в шаблонах соответствия, должны быть экранированы:
\ + * ? [ ^ ] $ ( ) { } = ! < > | : -
Подмаски (Subpatterns):
Подмаски заключаются в круглые скобки и могут быть вложенными. Выделение части выражения в качестве подмаски делает 2 вещи:
-
Определяет набор альтернатив. Например, подмаска cat(aract|erpillar|) соответствует одному из слов "cat", "cataract" и "caterpillar". Без заключения в скобки она бы соответствовала словам "cataract", "erpillar" или пустой строке.
-
Подмаска становится захватываемым и возвращается в качестве соответствующего аргумента в PCRE функциях. Нумеруются захватываемые подмаски слева направо начиная с 1.
Например, строка "the red king", сопоставляемая подмаске ((red|white) (king|queen)), вернёт в качестве аргументов слова "red king", "red" и "king", которые будут пронумерованы 1, 2 и 3 соответственно.
Когда от подмаски не требуется функционала захвата подстрок, после открывающей круглой скобки ставится символ "?:". Такая подмаски исключается из нумерации захватываемых подмасок. Например, если строка "the white queen" сопоставляется с подмаской the ((?:red|white) (king|queen)), возвращаемые захваченные подстроки будут "white queen" и "queen" и будут пронумерованы 1 и 2 соответственно. Максимальное количество захватываемых подмасок в выражении - 99. Максимальное кол-во всех подмасок (захватываемых и нет) - 200.
Между знаками "?" и ":" в не захватываемой подмаске можно использовать дополнительные опции. Следующие два шаблона:
(?i:saturday|sunday) (?:(?i)saturday|sunday)
соответствуют одинаковому набору строк. Так как альтернативы обрабатываются слева направо и опции действуют до конца подмаски, опция, установленная в первой части влияет на последующие. Поэтому приведённые выше шаблоны соответствуют как "SUNDAY", так и "Saturday".
Также можно использовать именованные подмаски с помощью синтаксиса (?P<name>pattern). Эта подмаска будет индексирована в массиве совпадений кроме обычного числового индекса, еще и по имени name. В PHP 5.2.2 было добавлено два альтернативных синтаксиса: (?<name>pattern) и (?'name'pattern).
Иногда бывает необходимо иметь несколько совпадений, исключающих друг друга. Обычно, каждое такое совпадение получает свой собственный номер, даже если шаблон позволяет совпасть только одному из них. Синтаксис (?| позволяет обойти это поведение и убрать дублирующиеся номера. Рассмотрим следующее регулярное выражение, сопоставленное со строкой Sunday:
(?:(Sat)ur|(Sun))day
Здесь Sun сохраняется в ссылке 2, тогда как ссылка 1 пуста. Если же совпадет Sat, то она будет помещена в ссылку 1, а ссылка 2 вообще не будет существовать. Использование (?| в шаблоне решает эту проблему:
(?|(Sat)ur|(Sun))day
В этом шаблоне обе подмаски Sun и Sat будут сохранены под номером 1.