Специальные переменные, используемые в регулярных выражениях
11.1. Концепция динамической видимости переменных
В языках программирования существуют глобальные и закрытые (private) переменные, которые объявляются директивой my (…). В Perl специальные глобальные переменные, такие, как $_, $1, @ARGV, не объявляются и доступны из любой точки программы. Если вы не используете директиву use strict (или use strict 'vars' ) и объявляете в программе переменные ( $a и т.д.), то эти переменные будут глобальными для данного пакета. Если вы употребили директиву use strict, вы должны будете объявлять эти переменные директивой our.
Переменные my имеют лексическую видимость и видны в минимальном блоке { … }, в котором находится директива my. (Это утверждение также относится к блоку кода Perl (?{…} ) внутри регулярного выражения.
В языке Perl существует также концепция динамической видимости. Perl может сохранить значение глобальной переменной перед входом в блок и восстановить его перед выходом из него. Код внутри блока будет работать с двойником этой глобальной переменной, которой может присвоить другое значение. Динамическая видимость создается директивой local. Например:
$_=1; { local $_=2; print "$_\n"; } print "$_\n";
2 1
Внутри блока программа работает с копией переменной $_, которая имеет то же имя, а при выходе из блока эта копия уничтожается, и программе становится доступна переменная $_, которая существовала до входа в этот блок. Директива local иногда применяется в подпрограммах, хотя в них логичнее создавать внутренние переменные директивой my. Директива local не применяется к переменным, созданным директивой my.
11.2. Специальные переменные, изменяемые при поиске
При совпадении в операторах m/…/ и s/…/…/ изменяют значения специальные переменные регулярных выражений. Напомню их.
- $` - текст перед совпадением всего регулярного выражения.
- $& - текст, с которым совпало все регулярное выражение.
- $' - текст после совпадения всего регулярного выражения.
- $1 - текст, совпавший с первой парой захватывающих скобок.
- $2 - текст, совпавший со второй парой захватывающих скобок.
- …
- $99 - текст, совпавший с 99-й парой захватывающих скобок.
- $+ - Содержимое нумерованной переменной ($1, $2, … ,$99) с максимальным номером (на момент использования переменной $+).
- $^N - Содержимое нумерованной переменной ($1, $2, … ,$99), соответствующей последней только что закрытой паре скобок (на момент использования переменной $^N ). (Эту переменную в отличие от $+ почему-то можно читать сразу после закрывающей захватывающей скобки. Возможно, эта ошибка уже исправлена в новой версии Perl.)
- @- - массив начальных индексов совпадений в целевом тексте. $-[0] соответствует переменной $&, $-[1] - переменной $1, …, $-[99] - переменной $99.
- @+ - массив конечных индексов (т.е. индексов первого символа после совпадения) совпадений в целевом тексте. $+[0] соответствует переменной $&, $+[1] - переменной $1, …, $+[99] - переменной $99.
- $^R - стоит немного особняком и допускает присваивание. Результат последней по времени исполняемой части встроенного кода, который расположен не в условии условной конструкции (? if then [ | else ] ).
Все эти переменные кроме $^R предназначены только для чтения. Многие авторы по ошибке считают, что переменная $^R тоже только читается, но мы убедились в противоположном. Также они ошибаются, говоря, что вне регулярного выражения эта переменная не имеет смысла.
Все эти переменные изменяют свое значение только при успешном поиске, при неудачном они хранят последнее присвоенное значение.
Переменные $1, $2, …, $99 устанавливаются сразу после закрытия соответствующей скобки, поэтому их можно использовать во встроенном коде или динамических регулярных выражениях внутри регулярного выражения. (Вне встроенного кода и динамических регулярных выражений используйте обратные ссылки \1, \2, …, \99.) То же относится к переменным $+, $^N, @- и @+. Переменная $^R получает значение после завершения соответствующего встроенного кода Perl.
В случае применения модификатора g (gc) при каждой итерации значения этим переменным присваиваются заново. Поэтому в операторе подстановки эти переменные всегда соответствуют соответствующим фрагментам текста из последней итерации.