首頁>技術>

正則表示式引擎是正則表示式匹配演算法的基礎。其有多種不同的實現,但大多數都是基於Henry Spencer的NFA引擎。

正則引擎有兩個大分類,DFA和NFA,像Perl、Java、.Net、PHP、Python、Ruby……等大多是工具都是用了NFA引擎。少數廣泛被使用的工具如mawk使用了POSIX NFA引擎(NFA的一種變種)。以高效著稱的工具採用了更為高效的DFA引擎。諸如GNU awk,GNU egrep和Tcl之類的一些工具結合了NFA / DFA兩種引擎,將兩者的優點結合在一起。

基於不同型別引擎的實現的正則表示式,主要有以下幾點差異。

語法匹配內容零寬斷言(環視) 功能捕獲功能效能

所有的引擎都會對文字做從左向右的最長匹配,但具體細節取決於使用了何種引擎。

傳統的NFA引擎

NFA引擎中使用的非確定有限狀態機(Nondeterministic finite automation)是一種由要匹配的表示式驅動的演算法。這使得正則表示式像一個小的程式語言一樣,可控制引擎在匹配失敗時候的行為。

正則引擎從正則表示式其實位置開始,嘗試正則表示式與文字的開頭進行匹配,如果匹配成功,都前進一個配置,否則文字一直前進到下一個字元,直到匹配。 如果正則表示式需要作出選擇(例如使用替代詞或可選的量詞),它將選擇其中之一,並記住其他選擇以及在文字中進行選擇的位置。如果在之後的處理中,匹配失敗,並且還有其他可選的路徑,則引擎將回溯做之前作出選擇的位置,並嘗試其他的選擇。如果沒有其他可用的替代方案,則匹配失敗,引擎前進到下一個字元並從頭開始匹配正則表示式。

如果引擎到達了正則表示式的末尾並且所有內容都已匹配,則引擎就會認為匹配成功,並最終放棄所有剩下的替代方法,甚至不再繼續探索。這裡有很重要的一點:選擇不同路徑的順序很重要,它決定是是否能做到最長匹配。

POSIX NFA 引擎

POSIX NFA引擎類似於傳統NFA引擎,但是當找到成功的匹配項時,它將會記錄匹配結果,並且嘗試其他可用的替代方法以查詢是否可以找到更長的最左邊的匹配。 這消除了傳統NFA引擎中不能保證最長最左匹配的問題。

以弗裡德爾(Friedl)的書中的這個有趣的例子為例:用one(self)?(selfsufficient)?去匹配oneselfsufficient,傳統的NFA將匹配oneself,而POSIX NFA將匹配oneselfsufficient,因為(self)?有兩種選擇,匹配self或者啥都不匹配,顯然最終匹配到的更長。

DFA引擎

DFA引擎中使用的確定性有限自動機(Deterministic finite automaton)是一種由要搜尋的文字驅動的演算法。 對於搜尋到的文字中的每個字元,DFA引擎只會檢視一次。 實際上,它相當於並行嘗試了NFA中所有可能的替代方法,並將返回其中最長的匹配。

這種方法確實更高效,但也有很多缺點:

11
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 網站效能調優實戰