讀古今文學網 > 精通正則表達式(第3版) > qr/…/運算符與regex對像 >

qr/…/運算符與regex對像

The qr/…/Operator and Regex Objects

在第2章和第6章已經簡要介紹過(☞76,277)一元運算符qr/…/,其運算元為正則表達式,返回regex對象。返回的對象可以被之後的正則運算符用來匹配、替換、分割,或者可以作為其他的更長表達式的一部分。

regex對像主要用來把正則表達式封裝為一個單元,構建大的正則表達式,以及提高效率(在正則表達式編譯時提高控制能力,討論見下文)。

291頁已經介紹過,用戶可以使用自己的分隔符,例如qr{…}或者qr!…!。它還支持核心修飾符/i、/x、/s、/m和/o。

構建和使用regex對像

Building and Using Regex Objects

下面的表達式來自第2章(☞76):

第一行代碼把匹配主機名所用的簡單正則表達式封裝為regex對象,保存到變量$Hostname-Regex中。下一行使用該變量構建匹配HTTP URL的regex對象,保存到$HttpUrl中。構建完成之後就可以以多種方式使用,例如:

用來檢測,或者:

用來搜索和顯示所有的HTPP URL。

如果按照第5章的講解(☞205)修改$HostnameRegex:

它的使用方式與之前的例子相同(開頭沒有「^」,結尾沒有「$」,也沒有捕獲型括號),所以,我們的替換不受限制。這樣能得到更準確的$HttpUrl。

匹配模式(即使不設置)是不可更改的

qr/…/支持292頁介紹的核心修飾符。regex對像一旦構建完成,對應的匹配模式就不能更改了,即使regex對像所在的m/…/有自己的修飾符也是如此。下面的代碼就不正確:

這裡希望用/x修飾$WordRegex的匹配模式,但是這並不管用,因為在$WordRegex生成時修飾符(即使不設置)被鎖定在qr/…/中。所以,修飾符必須在恰當的時候使用。

下面的代碼則沒有問題:

現在來比較開始的代碼和下面的代碼:

這段代碼沒問題,儘管$WordRegex生成時沒有任何修飾符。因為$WordRegex是普通變量,保存普通的字符串,用作 m/…/的插值。因為各方面的原因,用字符串構建正則表達式比regex對像要麻煩得多,比如在這個例子中,必須記住$WordRegex必須和/x一起使用才行。

我們也可以只使用字符串解決這個問題,只需要在表達式中設定模式修飾範圍(☞135):

此時,m/…/的正則文字插值之後,正則引擎接收到「^((?x:\b·\w+·\b))」,這就是我們期望的結果。

其實這就是生成regex對象的邏輯過程,只是regex對像對於每個模式修飾符,都明確定義了「on」或「off」的狀態。用qr/\b·\w+·\b/x生成「(?x-ism:\b·\w+·\b)」。請注意模式修飾符的設定「(?x-ism:…)」,這裡啟用了/x,禁止了/i、/s和/m。也就是說,無論是否指定qr/…/的修飾符,regex對像總是「鎖定」在某個模式下。

探究regex對像

Viewing Regex Objects

前面討論了regex對像綜合正則表達式和模式修飾符——例如「(?x-ism:…)」——的邏輯過程。如果在Perl期望接收字符串的地方使用regex對象,Perl會把它轉換為對應的文本表示方式,例如:

這就是第304頁的$HttpUrl的轉換結果:

把regex對像轉換為字符串的功能在調試時很有用。

用regex對像提高效率

Using Regex Objects for Efficiency

使用regex對象的主要原因之一是便於控制。為了提高效率,Perl會把正則表達式編譯為內部形式。第6章簡要介紹了正則表達式編譯的一般知識,但是更複雜的Perl相關問題,包括 regex 對像之類,都在「正則表達式編譯、/o 修飾符、qr/…/和效率」(☞348)中詳細討論。