Интерполяция переменных и метасимволы \U, \u, \L, \l, \Q, \E
7.2 Интерполяция переменных и кода в регулярное выражение
Т.к. регулярное выражение предварительно обрабатывается как строка, заключенная в кавычки (если оно не было ограничено апострофами), то интерполяция значений переменных и результата выполнения кода Perl в регулярное выражение происходит по аналогичным правилам. Но здесь могут встретиться нюансы, которые связаны с тем, что регулярные выражения имеют свои метасимволы.
Авторы книг по Perl не упоминают, как происходит интерполяция переменной с индексами, ведь символ [ является метасимволом внутри шаблонов.
my @a=('abc','def'); $_='def'; print $& if /^$a[1]$/;
Напечатается def.
Как видим, конструкция […] после имени переменной интерпретируется как индекс. Если же интерполируется скалярная переменная, после которой идет класс, то транслятор выдает ошибку:
#!/usr/bin/perl -w use strict; my $a=2; $_='21'; print $& if /^$a[1]$/; Global symbol "@a" requires explicit package name at a.pl line 6. Execution of a.pl aborted due to compilation errors.
Здесь не поможет заключение имени переменной в фигуный скобки: ${a}, ошибка останется той же. Если отделить имя переменной от квадратной скобки пробелом, то программа работает верно:
#!/usr/bin/perl -w use strict; my $a=2; $_='21'; print $& if /^$a [1]$/x;
На выходе имеем 21.
А если мы не планируем использовать модификатор x? Тогда может помочь такое искусственное решение:
my $a=2; $_='21'; print $& if /^$a(?#)[1]$/;
Опять получаем 21.
Мы отделили имя переменной от скобки конструкцией комментария. Т.к. интерполяция переменных происходит раньше удаления комментариев, этот метод работает. Также можно было бы разделить имя со скобкой каким-либо нейтральным подшаблоном, например:
my $a=2; $_='21'; print $& if /^$a(?=)[1]$/;
И снова выводится 21.
Опережающая проверка (?=) всегда возвращает истину, т.к. пустой фрагмент в тексте можно встретить всюду.
Вот еще подобный разделитель, показывающий также, что иногда надо использовать фигурные скобки для обособления имени от следующих за ними символов, которые могут входить в имена:
my $a=2; $_='21'; print $& if /^${a}a{0}[1]$/;
Опять 21.
Мы разделили имя и класс подшаблоном a{0}, который равносилен пустому фрагменту.
Теперь рассмотрим интерполяцию переменной с двумя индексами:
my @a=([1,2],[3,4]); $_='2'; print $& if /^$a[0][1]$/;
На печати получаем 2. Отсюда вывод: конструкции […] интепретируются как индексы переменной, если они идут непосредственно после ее имени. Отделение классов от индексов происходит аналогично уже рассмотренным случаям с одним индексом.
Массивы в регулярные выражения тоже интерполируются как в строку, ограниченную двойными кавычками:
$"=','; my @a=(1,2,3); $_='1,2,3'; print $& if /^@a$/;
1,2,3
После интерполяции массива @a с учетом разделителя $"=',' регулярное выражение стало эквивалентно такому: /^1,2,3,4$/.