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

До настоящего момента мы рассматривали круглые скобки, которые «захватывали» части совпадения и сохраняли их в переменных в памяти. Но что, если круглые скобки должны использоваться только для группировки? Возьмем регулярное выражение с необязательной частью, в котором должна сохраняться другая часть. В следующем примере строка «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.
Теги:
регулярные выражения
Добавлено: 20 Июля 2018 19:25:08 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...