2012-05-21 67 views
2

對於PCRE正則表達式,[abc]和(a | b | c)有什麼區別?[abc]和(a | b | c)之間的區別

+3

相關[使用交替或字符類的單個字符匹配?](http://stackoverflow.com/questions/4724588/using-alternation-or-character-class-for-single-character-matching)有一些有趣的答案。 – stema

+0

那個帖子很有幫助。謝謝 – user1032531

回答

8

問題中的模式匹配相同的文本。在實施方面,它們對應於不同的自動機和副作用(,即,它們是否捕獲子串)。

在下面的評論中,Garrett Albright指出了一個微妙的區別。鑑於(.|\n)匹配任何字符,[.\n]匹配文字點或換行符。儘管點在字符類中不再特殊,但其他字符(如-,^])以及諸如[:lower:]等序列在字符類中具有特殊含義。需要注意將特殊語義從一種上下文保留到另一種上下文中,但有時它可能是不可能的,例如\1作爲在字符類外部編寫$1的古代方式。在角色類中,\1總是與角色SOH匹配。

字符類([...])針對某些字符集中的某一個進行了優化,而替代方案(x|y)允許更改一般長度的選項。如果你牢記這些設計原則,你會看到更好的表現。正則表達式實現將源代碼(如/[abc]/)轉換爲有限狀態自動機,通常爲NFAs。我們認爲正則表達式引擎是幫助執行這些目標狀態機的或多或少的簿記員。足夠智能的正則表達式編譯器將爲等效的正則表達式生成相同的機器碼,但由於lurking exponential complexity的原因,這在一般情況下很難並且很昂貴。

有關正則表達式理論的可訪問性介紹,請參閱Mark Dominus的「How Regexes Work」。爲了更深入的研究,請考慮Peter Linz的An Introduction to Formal Languages and Automata

+0

你什麼時候使用一個? 「他們對應不同的自動機和子串捕獲」是什麼意思?謝謝 – user1032531

+0

如果a,b和c只是字母,當然(就像我認爲的意思)。如果他們能夠代表文字,顯然它是完全不同的語義。 – kratenko

+0

我發現有時方括號選項似乎不適合有趣的字符,如'\ n'或'\ r'。例如,要捕捉包含換行符的FOO和BAR之間的所有文本,'/ FOO((。| \ n)+)BAR /'有效,而'/ FOO([。\ n] +)BAR /'沒有。不過,這可能是特定於實現的。我發現了其他的差異,就像我無法回想起我的頭頂。無論如何,一般來說,我會先嚐試使用'[ab]',因爲它更具可讀性,如果事情似乎沒有奏效,那就試試'(a | b)'。 –

1

(閱讀格雷格的回答後):如果他們有不同的評價應該依賴於你給他們的任何程序。選擇你想要檢查的內容。你想檢查一堆有效的字符,或者你想檢查值。 - 有時看起來可能是一樣的,但它背後可能有不同的意圖。然後選擇反映你意圖的東西。

0

PCRE使用方括號的表格要快得多,特別是在啓用了JIT編譯的情況下。它只是在比特中檢查一下,而另一個重新讀取每個選擇的字符。我正在考慮一種可以檢測這種情況的優化,因爲很多人不知道可以在方括號內使用字符類,並且它們使用([a-z] | \ s)+而不是[a-z \ s] +。

相關問題