Опубликован: 18.06.2007 | Доступ: свободный | Студентов: 1418 / 43 | Оценка: 4.14 / 3.29 | Длительность: 12:44:00
ISBN: 978-5-94774-604-4
Лекция 7:

Интерполяция переменных и метасимволы \U, \u, \L, \l, \Q, \E

< Лекция 6 || Лекция 7: 123456 || Лекция 8 >

Если интерпретатор видит, что регулярное выражение требует интерполяции чего-нибудь, то это выражение будет транслироваться всякий раз перед его выполнением. Если вы уверены, что интерполируемые переменные не меняют своего значения, то можете поставить ко всему регулярному выражению модификатор 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}$/;

На печать выйдет 23.

После интерполяции регулярное выражение будет иметь вид /^[23]{2}$/.

Разумеется, в классы интерполируются также и переменные, содержащие метасимволы классов:

$_='123abc';
my $a='^\d';
print $& if /[$a]+/;

Будет напечатано abc.

После интерполяции регулярное выражение будет иметь вид /[^\d]+/.

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

#!/usr/bin/perl -w
use strict;

$_='z';
my $a=undef;
/^$a$/;

Будет напечатано:

Use of uninitialized value in concatenation (.) or string at a.pl line 6.

Если мы хотим интерполировать внутрь строки значение переменной $n, то просто напишем "\$n=$n text". А если надо интерполировать не число $n, а число $n+1 или другое выражение, тогда как? Можно, конечно, написать так: "\$n+1=".($n+1)." text", но это не будет интерполяция внутрь строки. Здесь можно прибегнуть к рассмотренному приему интерполяции кода внутрь строки: "\$n+1=${\($n+1)} text". Аналогично можно интерполировать выражения внутрь регулярных выражений. К примеру, если мы вместо квантификатора хотим использовать значение переменной $n, то напишем

$_='a';
my $n=1;
/^(a{$n})$/;
print $1;

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

Если хотим, к примеру, использовать квантификатор со значением $n+1, то можно написать так:

$_='aa';
my $n=1;
/^(a{${\($n+1)}})$/;
print $1;

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

< Лекция 6 || Лекция 7: 123456 || Лекция 8 >
Гулзира Урбисинова
Гулзира Урбисинова
Сергей Крупко
Сергей Крупко

Добрый день.

Я сейчас прохожу курс  повышения квалификации  - "Профессиональное веб-программирование". Мне нужно получить диплом по этому курсу. Я так полагаю нужно его оплатить чтобы получить диплом о повышении квалификации. Как мне оплатить этот курс?