Регулярные выражения Perl и их применение


         

Интерполяция переменных и кода в регулярне выражение - часть 2


Опять 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,4

После интерполяции массива @a с учетом разделителя $"=',' регулярное выражение стало эквивалентно такому: /^1,2,3,4$/.

Если интерпретатор видит, что регулярное выражение требует интерполяции чего-нибудь, то это выражение будет транслироваться всякий раз перед его выполнением. Если вы уверены, что интерполируемые переменные не меняют своего значения, то можете поставить ко всему регулярному выражению модификатор o, который отменит повторную компиляцию такого шаблона. Вместо этого будет использоваться его внутреннее скомпилированное представление, которое получилось перед первым его выполнением. А во внутреннем представлении переменные заменены их значениями.

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

Сравните:

my $a='abc'; $_='abc'; for my $count (0..1) { print "$&\n" if /^$a$/; $a='123'; $_='123'; }

Напечатается

abc 123

и

my $a='abc'; $_='abc'; for my $count (0..1) { print "$&\n" if /^$a$/o; $a='123'; $_='123'; }

Напечатается только

abc

Во втором случае в обоих повторах цикла совпадение отыскивается по тому же самому регулярному выражению /^abc$/, хотя переменная $a поменяла значение на '123'. В результате при втором повторе цикла совпадение с шаблоном не обнаруживается.

Модификатор o, как и модификаторы g и с, могут быть применены только ко всему регулярному выражению и не могут встречаться внутри него.

Как будут интерполироваться переменные, которые устанавливаются внутри регулярного выражения, в частности, нумерованные переменные $1, $2, …, $99? Так же, как и ваши переменные: своим значением, которое они имели до работы этого регулярного выражения. Поэтому не надейтесь, что в ходе выполнения регулярного выражения вы будете получать самые "свежие" их значения. Другое дело - встроенный код Perl и динамические регулярные выражения (которые мы рассмотрим в дальнейшем): здесь нет интерполяции переменных, а используются их текущие значения.

Внутри классов тоже происходит интерполяция переменных. В данном примере мы интерполируем два значения переменных с двумя индексами:

my @a=([1,2],[3,4]); $_='23'; print $& if /^[$a[0][1]$a[1][0]]{2}$/;




Содержание  Назад  Вперед