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


         

Экранирование метасимволов регулярных выражений


Если вы вставляете в регулярное выражение литерал из ввода пользователя или какую-либо переменную и хотите, чтобы переменная интерпретировалась как текст для поиска, а не как часть регулярного выражения, то для этого имеется эскейп-последовательность \Q, которая включает режим экранирования метасимволов регулярных выражений, таких, как [, *, +, {, ^, $, …: /\Q$userinput\E/. Экранирование осуществляется до эскейп-последовательности \E, а при ее отсутствии - до конца регулярного выражения.

Вставка ввода пользователя в регулярное выражение сопряжена с опасностью выполнения постороннего кода Perl, который может содержать вызов системных программ. Это является большой дырой в защите сервера. Поэтому переменную, содержащую ввод пользователя, надо заключать в специальную конструкцию \Q…\E. Вряд ли вы захотите искать или заменять что-то по регулярному выражению, которое вводит пользователь.

Результат аналогичен применению функции Perl quotemeta(). Но символы \ в неизвестных комбинациях (например, \F) не экранируются. Переменные типа $scalar и @array внутри метапоследовательности \Q…\E интерполируются, также интерполируются специальные переменные, которые должны интерполироваться внутри регулярных выражений.

Например:

$_='[a]bc$ '; print "'$&'" if /^\Q[a]bc$ \E$/;

Напечатается '[a]bc$ '. После символа $ внутри строки $_ и регулярного выражения стоит пробел. Если бы между символами $ и \ не было пробела, то внутри регулярного выражения возникла бы специальная переменная $\, которая стандартно содержит неопределенное значение. Она бы заменилась на пустой фрагмент, символ \ был бы отнят от буквы E и вместо завершителя метапоследовательности \Q…\E и метасимвола $ - конца текста - мы бы получили букву E, за которой стоит простой символ $:

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

$_='[a]bcE$'; print $& if /^\Q[a]bc$\E$/;

На печати оказывается следующее:

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

Мы получили предупреждение об использовании неинициализированной переменной ( а именно, $\) внутри регулярного выражения. Но совпадение все же было найдено.

Чтобы яснее проиллюстрировать этот пример, присвоим переменной $\ какое-либо значение, а также вставим его в исходную строку после буквы c:

$\='?'; $_='[a]bc?E$'; print $& if /^\Q[a]bc$\E$/;




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