PHP 8.3.4 Released!

Подшаблоны

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

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

  2. Настраивает подшаблон как подшаблон захвата подстроки, как показывает первый пункт. Функция модуля PCRE pcre_exec() через аргумент ovector возвращает вызывающей функции подстроку, которая соответствует подшаблону, когда совпадает полный шаблон. Функция подсчитывает открывающие круглые скобки с единицы слева направо, чтобы получить количество захватывающих подшаблонов.

Например, если строка «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

User Contributed Notes 1 note

up
-2
mike at eastghost dot com
8 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