轉載請注明出處 https://www.cnblogs.com/majianming/p/11823697.html
目前常見的正則表達引擎總體分為2種,DFA (確定型有窮狀態自動機) 和 NFA (非確定型有窮狀態自動機)
如果細分,NFA 可以分為傳統NFA和POSIX NFA
那么如何區分3者
如果某種正則引擎如果他不能匹配能很快給出結果,那么他可能是DFA
如果只有在能夠匹配的時候才能快速給出結果,那么就是傳統NFA
如果無論能不能匹配,匹配的時間都基本一致,那么就是POSIX NFA
why ?
首先先看 DFA,DFA 是文本主導的表達式引擎,實際上,對於確定的DFA表達式,狀態的個數是確定的,這個也是為什么是確定型有窮狀態
通過DFA 表達式,可以分析出所有可能的匹配路徑,也就是說,在匹配還沒開始的時候,所有路徑都已經確定了(如果遇到某個字符 就走某個指定的路徑),接下來需要做的就是在匹配文本,然后刪掉不符合的路徑,如果中途存在沒有的路徑,那么匹配失敗,如果到最后存在多條匹配成功的路徑,那么取匹配最長的路徑
另外DFA 不支持反向引用和環視
而NFA 是表達式主導的引擎,也就是說實際上是拿文本到表達式測試,如果成功就繼續匹配,失敗就回溯或者選擇其他分支或者報告匹配失敗
在NFA中分為兩種引擎,傳統NFA和POSIX NFA
傳統NFA和POSIX NFA的區別是傳統NFA 如果如果找到一個匹配,那么就會直接報告這個匹配,POSIX NFA會嘗試所有可能的匹配,如果有多個匹配,返回最長最左的匹配
所以在能夠匹配的時候NFA 只需要找到一個匹配就能返回了,相對速度會很快,因為POSIX NFA 需要嘗試所有可能才會報告是否匹配成功,所以時間是一致的。
引擎類型 | 程序 | 忽略優先量詞(懶惰) | 捕獲型括號 | 回溯 |
---|---|---|---|---|
DFA | awk (大多數版本)、egrep (大多數版本)、flex 、lex 、MySQL、Procmail |
不支持 | 不支持 | 不支持 |
傳統型 NFA | GNU Emacs、Java、grep (大多數版本)、less 、more 、.NET 語言、PCRE library、Perl、PHP(所有三套正則庫)、Python、Ruby、sed(大多數版本)、vi |
支持 | 支持 | 支持,但性能差 |
POSIX NFA | mawk 、Mortice Kern Systems’utilities、GNU Emacs(明確指定時使用) |
不支持 | 支持 | 支持,但性能差 |
DFA/NFA 混合 | GNU awk 、GNU grep/egrep 、Tcl |
支持 | 支持 | DFA 支持 |