2009-12-02 29 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