Как оператор qr / STRING / в Perl решает, нужно ли компилировать STRING? - PullRequest
15 голосов
/ 02 декабря 2009

документы для qr/STRING/ говорят:

Этот оператор указывает (и, возможно, компилирует) свой STRING как регулярное выражение.

Что меня беспокоит, так это часть в скобках. Я не могу вспомнить ни одного случая, когда я не хочу, чтобы он скомпилировал регулярное выражение из STRING. Является ли это заявление в скобках просто ласкающими словами, чтобы охватить какой-то будущий случай, когда компиляция нежелательна, или есть случай сегодня (или в более ранней версии Perl), где STRING не будет скомпилирован?

Ответы [ 3 ]

13 голосов
/ 02 декабря 2009

Часть «возможно, скомпилирует» документации, вероятно, относится к ситуациям, подобным показанным ниже, где аргумент qr// является уже скомпилированным регулярным выражением:

use re 'debug';

$re1 = qr/foo/;
$re2 = qr/$re1/;

При запуске этой программы отображается только одно скомпилированное регулярное выражение.

Независимо от намерения этого отрывка, хитрые намеки на внутренние детали не делают ясной документацию. Я думаю, что документ патч будет полезным.

2 голосов
/ 02 декабря 2009

Редактировать: Этот ответ неправильный (или, по крайней мере, ошибочный), но в комментариях есть интересная дискуссия, которую стоит сохранить. Ответ Джона Сиракузы , кажется, на правильном пути.


Документация для qr// гласит, что

STRING интерполируется так же, как УЗОР в м / УЗОР / .

, который предположительно включает в себя поведение не перекомпиляции регулярных выражений, для которых шаблон не изменился или не может измениться в случае не включения интерполированных переменных. Например, вам не нужно перекомпилировать этот шаблон на каждой итерации цикла:

foreach my $char ('a' .. 'z') {
    my $vowel = qr/[aeiou]/;
    say "$char is a vowel" if $char =~ $vowel;
}
1 голос
/ 02 декабря 2009

Если регулярное выражение содержит какие-либо интерполированные строки, оно всегда компилируется (возможно, нет, если вы используете ключ / 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...