Как оператор qr/STRING/в Perl решает, нужно ли компилировать STRING?
docs для qr/STRING/
скажите:
Этот оператор цитирует (и, возможно, компилирует) его STRING
как регулярное выражение.
Меня беспокоит роль в круглых скобках. Я не могу думать о каких-либо случаях, когда я не хочу, чтобы он компилировал регулярное выражение из STRING
. Является ли это в скобках утверждение только ласковыми словами, чтобы охватить какой-либо будущий случай, когда компиляция не нужна или есть ли сегодняшний случай (или в более ранней версии Perl), где STRING
не будет скомпилирован?
Ответы
Ответ 1
"Возможно, компилирует" часть документации, вероятно, относится к ситуациям, подобным приведенным ниже, где аргумент qr//
является уже скомпилированным регулярным выражением:
use re 'debug';
$re1 = qr/foo/;
$re2 = qr/$re1/;
Запуск этой программы показывает только одно компилируемое регулярное выражение.
Независимо от намерений этого прохода, лукавые намеки на внутренние детали не дают четкой документации. Я думаю, что патч doc был бы полезен.
Ответ 2
Изменить: этот ответ неправильный (или, по крайней мере, ошибочный), но есть интересные обсуждения в комментариях, которые стоит сохранить. Ответ на вопрос Сиракузы, кажется, на правильном пути.
В документации для qr//
указано, что
STRING интерполируется так же, как и PATTERN в m/PATTERN/.
который предположительно включает в себя поведение не перекомпилированных регулярных выражений, для которых шаблон не изменился, или не может измениться в случае отсутствия интерполированных переменных. Например, вам не нужно перекомпилировать этот шаблон на каждой итерации цикла:
foreach my $char ('a' .. 'z') {
my $vowel = qr/[aeiou]/;
say "$char is a vowel" if $char =~ $vowel;
}
Ответ 3
Если регулярное выражение содержит любые интерполированные строки, оно всегда компилируется (возможно, нет, если вы используете переключатель /o - я признаюсь /o всегда меня путал). Если регулярное выражение содержит только буквальный текст, я верю, что ответ Адама правильный.
IIRC он предназначен для обработки этого сценария:
while (my $foo = $something->next) {
my $regex1 = qr/ab(cd+)ef?/; # only compiled once
my $regex2 = qr/ab${foo}*ef/; # compiled every time through the loop
# do stuff with $regex1 and $regex2
}