≪
≫

Оператор замены

Кратко рассмотрим оператор замены 5. Он отличается от оператора поиска тем, что за регулярным выражением для поиска имеется выражение для замены найденного:

s/.../.../

Это выражение может включать нумерованные переменные. Оно вычисляется в скалярном контексте и в случае успешного поиска замещает найденный фрагмент текста.

Если регулярное выражение для поиска заключено в парные ограничители (скобки), то операнд замены заключается в собственные ограничители. Тогда между ограничителями регулярного выражения и замены могут стоять пробельные символы. Вот примеры:

з<...

s(„.) {...}

Если ограничителями операнда замены выступают апострофы, то выражение для замены рассматривается как строка, заключенная в апострофы, и интерполяции переменных при замене не происходит.

Оператор 5 может иметь модификатор g (Global). (Впрочем, оператор т также может иметь этот модификатор, но об этом речь пойдет дальше.) В этом случае поиск и замена продолжаются как бы в цикле с того места, где закончилась предыдущая замена текста, и до тех пор, пока поиск находит фрагменты, соответствующие регулярному выражению. Как результат, оператор замены возвращает число сделанных замен или пустую строку, если замен не было. Если целевой строкой выступает переменная 5_, то ее и связку =~ писать не обязательно. Пример:

$_='aabbaa';

print s/a/c/g.

В результате получим вывод:

4

ccbbcc

Вот пример на использование нумерованных переменных:

$_='аа ЬЬ аа';

s/(w+)(?:s+w+){2}/$1 $1/;

print;

Получаем вывод:

аа аа

Куда делась третья группа букв? Она была удалена, т.к. оператор s заменяет всю часть текста, что соответствует шаблону поиска. Если бы мы хотели оставить третью группу букв нетронутой, то ее не надо было бы включать в поиск:

$_='аа ЬЬ аа1;

s/(w+)s+w+/$1 $1/;

print;

Получаем вывод:

аа аа аа

А если в поиск включается что-то, что должно остаться без изменений, то это надо взять в захватывающие скобки и в операнде замены на соответствующем месте поставить нужную нумерованную переменную.

Модификатор е в операторе замены

Оператор замены поддерживает модификатор е (Evaluation), которого нет в операторе поиска. В этом случае операнд для замены рассматривается как фрагмент кода Perl, который каждый раз во время замены выполняется аналогично функции eval, а полученный в скалярном контексте результат подставляется вместо найденного фрагмента текста. Это дает большую гибкость при замене текста. Более того, модификатор е может повторяться несколько раз, что влечет многократное применение функции eval к результату’ (столько раз, сколько раз повторен модификатор е). Заметим, что остальные модификаторы тоже могут повторяться, но это не влечет каких-либо последствий.

Рассмотрим такой пример на замену переменных их значениями:

ту $а=’а’;

$_=’This is $а';

s/($w+)/$1/;

print;

В результате будет напечатано

This is $а

В захватывающие скобки попала подстрока $а, операнд был интерполирован по правилам строк в кавычках и в результате интерполяции получился текст ‘&Ґ, который и заменил найденный фрагмент текста т.е. сам себя.

Теперь к оператору замены добавим модификатор е:

ту $а=’а’;

$_='This is $а';

s/($w+)/$1/e;

print;

В результате получается тот же вывод:

This is $а

Как это объяснить? Теперь операнд для замены был выполнен как код Perl. в результате получилась строка ‘$а’, которая опять заменила саму себя.

Добавим еще один модификатор е:

ту $а-’а’;

This is $а ;

s/($w+)/$1/ee;

print;

В результате получается текст

This is а

В этом случае после выполнения кода Perl 5/ получается строка которая опять выполняется как код Perl, что и дает ее значение ‘а’.

Теперь принцип ясен, мы можем продолжить эту аналогию и написать такую загадочную программу:

ту $Ь=’Ь';

ту $а=’$Ь';

$_='This is $а’;

s/($w+)/$1/eee;

print;

В результате выводится текст

This is b

Но вряд ли кому-либо на практике придется применять модификатор е больше двух раз.

 
Посмотреть оригинал