Подмаски

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

  1. Локализирует набор альтернатив. Например, шаблон cat(aract|erpillar|) соответствует одному из слов «cat», «cataract» или «caterpillar». Без использования скобок он соответствовал бы строкам «cataract», «erpillar» или пустой строке.

  2. Указывает на необходимость захвата подстроки (как показано выше). В том случае, если соответствие шаблону было найдено, подстрока, соответствующая подмаске, также передаётся обратно вызывающему при помощи аргумента 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 соответственно. Максимальное количество захватывающих подмасок — 65 535. Такие большие шаблоны могут не скомпилироваться, в зависимости от настроек libpcre.

Если в незахватывающей подмаске необходимо указать дополнительные опции, можно воспользоваться удобным сокращением: символ, обозначающий устанавливаемую опцию помещается между «?» и «:». Таким образом, следующие два шаблона

(?i:saturday|sunday)
(?:(?i)saturday|sunday)

соответствуют одному и тому же набору строк. Поскольку альтернативные версии берутся слева направо, и установленные опции сохраняют своё действие до конца подмаски, опция, установленная в одной ветке, также имеет эффект во всех последующих ветках. Поэтому приведённые выше шаблоны совпадают как с «SUNDAY», так и с «Saturday».

Также можно использовать именованные подмаски с помощью синтаксиса (?P<name>pattern). Эта подмаска будет индексирована в массиве совпадений кроме обычного числового индекса, ещё и по имени name. Также существуют два альтернативных синтаксиса: (?<name>pattern) и (?'name'pattern).

Иногда бывает необходимо иметь несколько совпадений, исключающих друг друга. Обычно, каждое такое совпадение получает свой собственный номер, даже если шаблон позволяет совпасть только одному из них. Синтаксис (?| позволяет обойти это поведение и убрать дублирующиеся номера. Рассмотрим следующее регулярное выражение, сопоставленное со строкой Sunday:

(?:(Sat)ur|(Sun))day

Здесь Sun сохраняется в ссылке 2, тогда как ссылка 1 пуста. В результате сопоставления Saturday в обратной ссылке 1 появляется Sat, в то время как обратная ссылка 2 не существует. Использование (?| в шаблоне решает эту проблему:

(?|(Sat)ur|(Sun))day

В этом шаблоне обе подмаски Sun и Sat будут сохранены под номером 1.

add a note add a note

User Contributed Notes 1 note

up
2
mike at eastghost dot com
9 years ago
(?:(?!string).)

?: makes a subpattern

?! is a negative look-ahead.

Putting negative look-ahead before the dot causes regex engine to first find any occurrence of the negative look-ahead string, and only then, if the negative look-ahead string is not present, should an arbitrary character (due to the dot) match.
To Top