re - Perl pragma 用於變更正規表示式行為
use re 'taint';
($x) = ($^X =~ /^(.*)$/s); # $x is tainted here
$pat = '(?{ $foo = 1 })';
use re 'eval';
/foo${pat}bar/; # won't fail (when not under -T
# switch)
{
no re 'taint'; # the default
($x) = ($^X =~ /^(.*)$/s); # $x is not tainted here
no re 'eval'; # the default
/foo${pat}bar/; # disallowed (with or without -T
# switch)
}
use re 'strict'; # Raise warnings for more conditions
use re '/ix';
"FOO" =~ / foo /; # /ix implied
no re '/x';
"FOO" =~ /foo/; # just /i implied
use re 'debug'; # output debugging info during
/^(.*)$/s; # compile and run time
use re 'debugcolor'; # same as 'debug', but with colored
# output
...
use re qw(Debug All); # Same as "use re 'debug'", but you
# can use "Debug" with things other
# than 'All'
use re qw(Debug More); # 'All' plus output more details
no re qw(Debug ALL); # Turn on (almost) all re debugging
# in this scope
use re qw(is_regexp regexp_pattern); # import utility functions
my ($pat,$mods)=regexp_pattern(qr/foo/i);
if (is_regexp($obj)) {
print "Got regexp: ",
scalar regexp_pattern($obj); # just as perl would stringify
} # it but no hassle with blessed
# re's.
(我們在這些範例中使用 $^X,因為它預設為 taint.)
當 use re 'taint'
生效時,且 taint 字串為正規表示式的目標時,正規表示式記憶體 (或在清單內容中由 m// 運算子傳回的值) 會被 taint。此功能在 taint 資料上的正規表示式運算並非用於擷取安全的子字串,而是執行其他轉換時很有用。
當 use re 'eval'
生效時,正規表示式允許包含 (?{ ... })
零寬度斷言和 (??{ ... })
延後子表示式,這些斷言和子表示式衍生自變數內插,而非實際出現在正規表示式中。這通常是不允許的,因為這是一個潛在的安全風險。請注意,當正規表示式從 taint 資料取得時,會忽略此 pragma,亦即,taint 正規表示式永遠不允許評估。請參閱 "(?{ code })" in perlre 和 "(??{ code })" in perlre。
針對此 pragma 的目的,預編譯正規表示式 (亦即 qr//
的結果) 的內插不視為變數內插。因此
/foo${pat}bar/
如果 $pat 是預編譯正規表示式,則允許,即使 $pat 包含 (?{ ... })
斷言或 (??{ ... })
子表示式。
請注意,這是一個實驗性功能,可能在未來的 Perl 版本中被更改或移除。
當 use re 'strict'
生效時,編譯正規表示式模式時會套用比平常更嚴格的檢查。這可能會導致產生比平常更多的警告,並導致更多情況變成致命錯誤,而不是只有警告。這樣做的目的是在編譯時找出並報告某些可能合法的內容,但很可能不是程式設計師的實際意圖。這會在作用域內自動開啟 "regexp"
警告類別(如果尚未開啟)。
以下模式是 "strict'
會偵測到,但平常不會偵測到的範例:
qr/\xABC/
"\x"
結構在沒有大括弧的情況下,後面應該緊接兩個十六進位數字;這個範例後面卻接了三個。這目前會評估為等於
qr/\x{AB}C/
也就是說,字元碼點值為 0xAB
的字元,後面接字母 C
。但由於 C
是十六進位數字,因此有合理的機率是意圖為
qr/\x{ABC}/
也就是 0xABC
處的單一字元。在 'strict'
下,\x
後面沒有緊接兩個十六進位數字會是一個錯誤。在沒有 'strict'
的情況下,如果只有一個十六進位數字,會產生警告;如果有多於兩個,則不會產生警告。
隨著我們累積經驗,預計 'strict'
的確切作用會隨著時間演進。這表示在當前 Perl 中可以在 'strict'
下編譯的程式,在未來的 Perl 中可能無法編譯,或者可能會產生更多或更少的警告。對於這一點,沒有向後相容性的承諾。此外,已經有關於啟用它的替代語法的提案。由於這些原因,除非關閉該類別,否則使用它會產生 experimental::re_strict
類別警告。
請注意,如果在 'strict'
內編譯的模式被重新編譯,例如透過內插到另一個模式中,在 'strict'
外部,則不會再次檢查其嚴格性。這是因為如果它在嚴格模式下運作,它一定會在非嚴格模式下運作。
當指定 use re '/flags'
時,給定的 flags 會自動新增到每個正規表示式,直到詞彙範圍結束。flags 可以是 'a'
、'aa'
、'd'
、'i'
、'l'
、'm'
、'n'
、'p'
、's'
、'u'
、'x'
和/或 'xx'
的任意組合。
no re '/flags'
會關閉 use re '/flags'
對給定旗標的作用。
例如,如果您希望所有正規表示式預設開啟 /msxx,只需將
use re '/msxx';
放在程式碼的最上方。
字元集 /adul
標記會互相抵消。因此,在此範例中,
use re "/u";
"ss" =~ /\xdf/;
use re "/d";
"ss" =~ /\xdf/;
第二個 use re
會隱含執行 no re '/u'
。
類似地,
use re "/xx"; # Doubled-x
...
use re "/x"; # Single x from here on
...
使用 use re
開啟正規表示式的其中一個字元集標記,會優先於 locale
pragma 和 unicode_strings
feature
。當其中一個標記在啟用狀態時關閉,則會回復到範圍內其他 pragma 所指定的行為。例如
use feature "unicode_strings";
no re "/u"; # does nothing
use re "/l";
no re "/l"; # reverts to unicode_strings behaviour
當 use re 'debug'
生效時,perl 會在編譯和使用正規表示式時發出偵錯訊息。輸出與使用 -Dr 開關執行啟用 -DDEBUGGING
的 perl 詮釋器所取得的輸出相同。根據比對的複雜度,輸出可能會非常龐大。使用 debugcolor
取代 debug
會啟用一種輸出形式,可讓您在了解 termcap 顏色順序的終端機上取得色彩豐富的顯示。將 $ENV{PERL_RE_TC}
設定為逗號分隔的 termcap
屬性清單,以用於開啟/關閉字串、開啟/關閉點前部分的醒目提示。請參閱 "perldebug 中的「偵錯正規表示式」 以取得其他資訊。
請注意,debug
模式的確切格式並非被視為 Perl 的官方支援 API。它僅供偵錯使用,且核心開發團隊可能會在未事先通知或於任何 Perl 版本(主要或次要)中棄用它的情況下,根據需要進行變更。任何輸出的文件都僅供參考。
從 5.9.5 開始,指令 use re 'debug'
及其等效指令與其他指令一樣,具有詞彙範圍。然而,它們同時具有編譯時間和執行時間的效果。
請參閱 "perlmodlib 中的「實用模組」。
類似地,use re 'Debug'
會產生偵錯輸出,不同之處在於它允許微調要發出的偵錯輸出。選項分為三組,分別與編譯、執行和特殊用途相關。
請注意,Debug
模式提供的選項及其產生的輸出的確切格式並非被視為 Perl 的官方支援 API。它僅供偵錯使用,且核心開發團隊可能會在未事先通知或於任何 Perl 版本(主要或次要)中棄用它的情況下,根據需要進行變更。任何格式或可用選項的文件都僅供參考,且可能會在未事先通知的情況下進行變更。
選項如下
開啟所有「額外」除錯選項。
在配對期間啟用除錯擷取群組儲存。警告,這可能會產生極大的輸出。
啟用增強的 TRIE 除錯。增強 TRIEE 和 TRIEC。
啟用引擎中狀態的除錯。
啟用引擎中遞迴堆疊的除錯。啟用或停用此選項也會自動對狀態除錯執行相同的動作。此輸出的結果可能相當龐大。
啟用 \G 修改器的除錯。
啟用增強的最佳化除錯和起點最佳化。除了除錯正規表示式引擎本身之外,可能沒有什麼用處。
在最佳化階段之前啟用編譯模式的傾印。
當 Perl 遇到萬用字元子模式時(請參閱 "perlunicode 中的「屬性值中的萬用字元」),它會暫停編譯主模式,編譯子模式,然後與所有合法可能性進行比對,以確定子模式比對的實際碼點。之後,它會將這些碼點新增到主模式,並繼續編譯。
你可能很想看到你的子模式是如何編譯的,但你不太需要看到 Perl 如何與所有合法可能性進行比對,因為那是由 Perl 控制,而不是你。因此,編譯部分的偵錯資訊會由其他選項指定,但比對部分的偵錯輸出通常會被抑制。
你可以使用 WILDCARD 選項來啟用此子模式比對的偵錯輸出。小心!這可能會產生大量的輸出,而且你可能不太了解 Perl 為什麼會這麼做。但它可能有助於你了解為什麼事情沒有按照你的預期進行。
請注意,此選項本身不會產生任何偵錯資訊輸出。它的作用是停止在萬用字元編譯的比對部分中,抑制與執行相關的偵錯資訊的正常抑制。你還必須指定你想要的執行偵錯資訊,例如同時包含 EXECUTE 選項。
這些是有用的捷徑,可以節省輸入。
從 5.9.5 版開始,指令 use re 'debug'
及其等效指令具有詞彙範圍,其他指令也是如此。但是它們同時具有編譯時間和執行時間效果。
從 perl 5.9.5 開始,'re' 除錯包含許多可以選擇性匯出到呼叫者名稱空間的公用程式函數。它們列在下方。
如果參數是透過 qr//
傳回的已編譯正規表示式,則傳回 true;如果不是,則傳回 false。
這個函數不會因重載或祝福而混淆。在內部條款中,這會從 PERL_MAGIC_qr 結構中萃取正規表示式指標,因此不會被愚弄。
如果參數是透過 qr//
傳回的已編譯正規表示式,則這個函數會傳回樣式。
在清單內容中,它會傳回一個兩個元素的清單,第一個元素包含樣式,第二個元素包含編譯樣式時使用的修改器。
my ($pat, $mods) = regexp_pattern($ref);
在純量內容中,它會傳回與 perl 在字串化具有相同樣式的原始 qr//
時相同的內容。如果參數不是已編譯的參照,則這個常式會傳回 false 但在純量內容中已定義,而在清單內容中傳回空清單。因此,下列內容
if (regexp_pattern($ref) eq '(?^i:foo)')
將會沒有警告,而不管 $ref 實際上是什麼。
與 is_regexp
相同,這個函數不會因物件的重載或祝福而混淆。
傳回最後成功比對的命名緩衝區內容。如果 $all 為 true,則傳回包含每個緩衝區一個條目的陣列參照;否則,傳回第一個已定義的緩衝區。
傳回最後成功比對中定義的所有命名緩衝區的清單。如果 $all 為 true,則傳回所有已定義的名稱;如果不是,則只傳回參與比對的名稱。
傳回用於最後成功比對的樣式中定義的不同名稱數量。
注意:這個結果永遠是定義的不同命名緩衝區的實際數量,它可能實際上與 regnames()
和相關常式傳回的結果不符,當這些常式未呼叫具有 $all 參數設定時。
如果參數是透過 qr//
傳回的已編譯正規表示式,則這個函數會傳回最佳化器認為是樣式中最長的錨定固定字串和最長的浮動固定字串。
固定字串定義為必須出現才能讓樣式比對的子字串。錨定固定字串是必須出現在比對開頭特定偏移量的固定字串。浮動固定字串定義為可以在比對開頭的特定位置範圍內出現的固定字串。例如,
my $qr = qr/here .* there/x;
my ($anchored, $floating) = regmust($qr);
print "anchored:'$anchored'\nfloating:'$floating'\n";
會產生
anchored:'here'
floating:'there'
由於模式中的 here
出現在 .*
之前,因此可以精確地確定其位置。但是,there
則不然;它可能會出現在錨定字串出現後的任何位置。Perl 使用這兩者進行最佳化,偏好較長者,或者如果它們相等,則偏好浮動者。
注意:這不一定是最明確的錨定和浮動字串。這將是您正在使用的 Perl 最佳化器認為最長的字串。如果您認為結果錯誤,請透過 perlbug 工具程式回報。
如果參數是 qr//
回傳的已編譯正規表示式,則此函式會回傳在編譯時發現的最佳化資訊的雜湊參考,因此我們可以針對它撰寫測試。如果給定任何其他參數,則回傳 undef
。
預期雜湊內容會隨著我們開發新的最佳化方式而不時變更 - 不應假設穩定性,即使在 perl 的次要版本之間也不應如此。
對於目前的版本,雜湊將具有以下內容
整數,任何可以匹配字串中的最少字元數。
整數,匹配後 $&
中可以包含的最少字元數。(例如考慮 /ns(?=\d)/
。)
整數,在 pos()
之前開始匹配的字元數。
布林值,TRUE
表示不應使用找到的任何錨定/浮動子字串。(CHECKME:顯然這是針對沒有浮動子字串的錨定模式設定的,但從未使用過。)
布林值,TRUE
表示最佳化資訊就是正規表示式所包含的所有內容,因此根本不需要進入正規表示式執行時間引擎。
布林值,如果模式錨定到字串開頭,則為 TRUE
。
布林值,如果模式錨定到字串內的任何行開頭,則為 TRUE
。
布林值,如果模式錨定到前一次匹配的結尾,則為 TRUE
。
布林值,如果開始類別只能匹配執行階段的第一個,則為 TRUE
。
布林值,如果 /.*/
已隱式轉換為 /^.*/
,則為 TRUE
。
一個位元組字串,分別代表任何配對都必須包含的錨定或浮動子字串,或如果找不到此類子字串,或如果子字串需要 utf8 來表示,則為 undef。
一個 utf8 字串,分別代表任何配對都必須包含的錨定或浮動子字串,或如果找不到此類子字串,或如果子字串只包含 7 位元 ASCII 字元,則為 undef。
一個整數,從配對位置開始計算的字元第一個偏移量,我們應該在其中尋找對應的子字串。
一個整數,從配對位置開始計算的字元最後一個偏移量,我們應該在其中尋找對應的子字串。
對於錨定而言會被忽略,因此可以是 0 或與最小值相同。
FIXME:不確定這是什麼,與回溯有關。regcomp.c 說:當最終模式編譯完成,並且資料從 scan_data_t 結構移到 regexp 結構中時,會將有關回溯的資訊納入考量,而原本會遺失的資訊會預先計算在相關字串的 end_shift 欄位中。
一個常數字串,為「anchored」、「floating」或「none」之一,用來表示應先檢查哪個子字串(如果有)。
字元類別(「開始類別」)的字串表示,必須是任何配對的第一個字元。
TODO:說明表示。