Оператор замены
Кратко рассмотрим оператор замены 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
Но вряд ли кому-либо на практике придется применять модификатор е больше двух раз.