2009-12-02 26 views
15

docsqr/STRING/说:Perl中的qr/STRING /运算符如何决定是否编译STRING?

这个操作符引号(并可能编译)其作为 正则表达式STRING

让我担心的是圆括号中的部分。我想不出任何我不希望它从STRING中编译正则表达式的情况。这个括号内的语句是否仅仅是为了涵盖某些将来不需要编译的案例,或者今天(或者在早期版本的Perl中)不会编译STRING的案例?

+9

“黄鼠狼话”?在我们的圣经中?你在开玩笑吧。 – innaM 2009-12-02 15:33:45

+2

是的,那些是黄鼠狼的单词。 – ysth 2009-12-02 18:28:13

回答

13

的“可能编写的”文件的一部分可能是指情况如下所示的一个,这里的参数qr//是一个已编译的正则表达式:

use re 'debug'; 

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

运行该程序只显示正在编译的一个正则表达式。

无论该段落的意图如何,对内部细节的狡猾暗示都没有明确说明文档的作用。我认为一个文档补丁将是有益的。

+1

宾果!使用'use re'debug''运行这个确认。 – innaM 2009-12-02 17:52:18

1

如果正则表达式包含任何内插字符串,它总是编译(也许不是如果你使用/ 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 
} 
+1

如果这就是它的意思,那么它的措辞非常糟糕。 – 2009-12-02 16:14:02

2

编辑:这个答案是错的(或至少是误导),但在这值得保留意见的一些有趣的讨论。 John Siracusa's answer似乎是在正确的轨道上。


qr//文档状态

STRING被内插相同的方式,以m/PATTERN PATTERN /。

这大概包括不重新编译模式没有改变的正则表达式的行为,或者在不包括插入变量的情况下不能改变的行为。例如,你不需要重新编译在每次循环迭代这种模式:

foreach my $char ('a' .. 'z') { 
    my $vowel = qr/[aeiou]/; 
    say "$char is a vowel" if $char =~ $vowel; 
} 
+0

这与我引用的部分有什么关系? Perl缓存编译的事实并不意味着'$ vowel'不会被引用和编译版本的'STRING'。我所问的短语似乎表示'qr/STRING /'可能会返回带引号但未编译的'STRING'版本。我询问当前或过去是否有任何情况下,qr/STRING /'不返回编译的正则表达式。如果没有这样的情况,那么我应该提交一个补丁来澄清这个声明。 – 2009-12-02 16:46:00

+0

qr运算符在每次遇到时都将其内容编译为正则表达式。 (无论存在/ o修饰符,它都会这样做。)提升循环上方的$ vowel = qr/[aeiou] /行大致使你在我的系统上的执行速度加倍。 – 2009-12-02 16:50:23

+1

@John Siracusa虽然似乎有一个缓存,但请检查以下代码:http://gist.github.com/247337如果每次都重新编译,那么'diff'和'same'的运行时间将会相同,但“相同”的速度大约快了三倍。我认为你所看到的时间差异是创建'$ vowel'变量并将缓存的编译正则表达式分配给它的时间。 – 2009-12-02 16:56:35