Несохраняющие круглые скобки

До настоящего момента мы рассматривали круглые скобки, которые «захватывали» части совпадения и сохраняли их в переменных в памяти. Но что, если круглые скобки должны использоваться только для группировки? Возьмем регулярное выражение с необязательной частью, в котором должна сохраняться другая часть. В следующем примере строка «bronto» является необязательной частью выражения, но чтобы сделать ее таковой, мы должны сгруппировать эту последовательность символов с круглых скобках. Позднее в этом шаблоне конструкция альтернативы выбирает между steak и burger, и мы хотим знать, какая из этих строк была обнаружена.

if (/(bronto)?saurus (steak|burger)/) {
print "Fred wants a $2\n";
}

Даже если bronto отсутствует в строке, эта часть шаблона соответствует переменной $1. Напомним: чтобы решить, какой переменной соответствует та или иная часть шаблона, Perl просто считает открывающие круглые скобки. Нужная нам часть оказывается в переменной $2. В более сложных шаблонах ситуация оказывается еще более запутанной.
К счастью, в регулярных выражениях Perl предусмотрена возможность использования круглых скобок исключительно для группировки, без сохранения данных в памяти.


Такие круглые скобки называются несохраняющими, а при их записи используется особый синтаксис.

После открывающей скобки ставится вопросительный знак и двоеточие (?:)1; тем самым вы сообщаете Perl, что круглые скобки будут использоваться только для группировки. Изменим наше регулярное выражение и заключим «bronto» в несохраняющие круглые скобки; та часть совпадения, которую мы хотим сохранить, теперь будет находиться в $1:

if (/(?:bronto)?saurus (steak|burger)/) {
print "Fred wants a $1\n";
}

Предположим, позднее регулярное выражение изменится, например в него добавится новая необязательная часть BBQ (с пробелом после Q). Этот элемент можно будет сделать необязательным и несохраняющим, а та часть совпадения, которую необходимо запомнить, по-прежнему будет храниться в $1. В противном случае нам пришлось бы сдвигать нумерацию всех переменных каждый раз, когда в регулярное выражение добавляются новые группирующие скобки:

if (/(?:bronto)?saurus (?:BBQ )?(steak|burger)/) {
print "Fred wants a $1\n";
}

Регулярные выражения Perl поддерживают и другие специальные последовательности с круглыми скобками для выполнения сложных, нетривиальных операций: опережающей и \ ретроспективной проверки, встроенных комментариев и даже выполнения кода в середине шаблона. За подробностями обращайтесь к man-странице perlre.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Perl на эту тему:
Автоматические переменные совпадения
Границы слов
Добавление пропусков (/x)
Другие модификаторы
Жизненный цикл переменных частичных совпадений