Подмаски
Подмаски ограничиваются круглыми скобками, которые могут быть вложенными. Использование части шаблона как подмаски имеет следующие функции:
-
Локализирует набор альтернатив. Например, шаблон
cat(aract|erpillar|)
соответствует одному из слов "cat", "cataract" или "caterpillar". Без использования скобок он соответствовал бы строкам "cataract", "erpillar" или пустой строке. -
Указывает на необходимость захвата подстроки (как показано выше). В том случае, если соответствие шаблону было найдено, подстрока, соответствующая подмаске, также передается обратно вызывающему при помощи аргумента ovector функции pcre_exec(). Открывающие круглые скобки нумеруются слева направо (начиная с единицы) и их порядковые номера используются для нумерации соответствующих подстрок в результате.
Например, если строка "the red king" сопоставляется с шаблоном
the ((red|white) (king|queen))
,
будут захвачены подстроки "red king", "red" и "king", с номерами 1, 2 и 3
соответственно.
На самом деле выполнение одновременно двух функций не всегда удобно.
Бывают случаи, когда необходима группировка альтернатив без захвата строки.
В случае, если после открывающей круглой скобки следует "?:", захват строки
не происходит, и текущая подмаска не нумеруется.
Например, если строка "the white queen" сопоставляется с шаблоном
the ((?:red|white) (king|queen))
,
будут захвачены подстроки "white queen" и "queen", и они будут пронумерованы
1 и 2 соответственно. Максимальное количество захватывающих подмасок - 65535.
Такие большие шаблоны могут не скомпилироваться, в зависимости от настроек libpcre.
В случае, если в незахватывающей подмаске необходимо указать дополнительные опции, можно воспользоваться удобным сокращением: символ, обозначающий устанавливаемую опцию помещается между "?" и ":". Таким образом, следующие два шаблона
(?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.