Построение эффективных регулярных выражений. Оператор qr/…/ и объекты регулярных выражений.
10.1.4. Ограничители в операторе qr/…/
В операторе qr/…/ в качестве ограничителей регулярного выражения не обязательно применять слэши, можно применять все те же символы, что и в операторе поиска m/…/. Но не применяйте в качестве ограничителей вопросительные знаки из-за их специального значения. Когда ограничителями выступают апострофы, при трансляции этого регулярного выражения не будет интерполяции переменных, если переменные будут там присутствовать. Вот пример с интерполяцией переменной:
my $a='ab'; $_='ab'; my $re=qr"^$a$"; print "\$re=$re\n"; print $& if /$re/;
Напечатается
$re=(?-xism:^ab$) ab
Теперь сделаем ограничителями апострофы и попробуем поискать строку '$a':
my $a='ab'; $_='$a'; my $re=qr'^$a$'; print "\$re=$re\n"; print $& if /$re/;
В результате напечатается
$re=(?-xism:^$a$)
Мы видим, что поиск закончился неудачей. Оказывается, символ $ перед именем переменной в операторе qr'…' все равно надо маскировать:
my $a='ab'; $_='$a'; my $re=qr'^\$a$'; print "\$re=$re\n"; print $& if /$re/;
Напечатается
$re=(?-xism:^\$a$) $a
То же касается текстов в интерполированных переменных: если после символа $ (и наверно, после символа @ ) стоят символы, при которых возможна интерпретация этих символов как имени переменной, то $ и @ должны быть замаскированы обратным слэшем. Символы внутри регулярных выражений, которые должны представлять сами себя, а не быть метасимволами, надо так же маскировать внутри оператора qr'…', как и в операторе qr/…/ со всеми остальными типами ограничителей. Это же касается и интерполируемых в регулярное выражение переменных (что более понятно). Вот пример: пытаемся найти символ |:
my $a='ab'; $_='|'; my $re=qr'^|$'; print "\$re=$re\n"; print "Found $&" if /$re/;
Будет напечатано
$re=(?-xism:^|$) Found
В этом примере регулярное выражение соответствует пустому фрагменту, т.к. оно ищет не символ |, а представляет из себя конструкцию выбора с двумя пустыми альтернативами. Если замаскировать символ | в операторе qr'…', то получим нужный результат:
my $a='ab'; $_='|'; my $re=qr'^\|$'; print "\$re=$re\n"; print "Found $&" if /$re/;
Напечатается
$re=(?-xism:^|$) Found |