• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數據加載中……

            NFA DFA Regex

            要深入了解正則表達式,必須首先理解有窮自動機。

            有窮自動機(Finite Automate)是用來模擬實物系統的數學模型,它包括如下五個部分:

            • 有窮狀態集States
            • 輸入字符集Input symbols
            • 轉移函數Transitions
            • 起始狀態Start state
            • 接受狀態Accepting state(s)


            下圖為一臺有窮自動機
            clip_image001

            可以看到,該自動機包含四個狀態q0, q1, q2, q3,兩個輸入字符a, b,轉移函數如圖所示,起始狀態為q0,接受狀態為q3

            有窮自動機,按照轉移函數的不同,又可分為確定型有窮自動機(Determinism Finite Automate, DFA),與非確定型有窮自動機(Non-determinism Finite Automate, NFA)。
            非確定有窮自動機容許轉移函數不確定,換句話說,對任意狀態,輸入任意一個字符,可以轉移到0個,1個或者多個狀態。
            下圖是一臺非確定有窮自動機,可以看到,對狀態q0輸入字符a,既可以轉移到q0,也可以轉移到q1,這就是非確定的意義所在。
            clip_image002


            對某個自動機來說,如果從起始狀態,接受一系列輸入字符,可以轉移到接受狀態,即認為這一系列字符可以被自動機接受。

            如果兩臺自動機能夠接受的輸入字符串(或者叫做正則語言”Regular Language)完全相同,則這兩臺自動機是等價的。
            可以證明,對于每一個非確定有窮自動機,都存在與之等價的確定型有窮自動機(證明略)。

            正則表達式就是建立在自動機的理論基礎上的:用戶寫完正則表達式之后,正則引擎會按照這個表達式構建相應的自動機(可能是NFA,也可能是DFA,但它們必定是等價的),若輸入一串文本之后,自動機抵達了接受狀態,則這串文本可以匹配用戶指定的正則表達式。

            下面是同一個正則表達式 a|ab 對應的NFADFA

            NFA

            clip_image003

            DFA

            clip_image004



            Mastering Regular Expression中,Friedl首先分析了NFADFA的區別,DFA比較快,但不提供Backtrack(回溯)功能,NFA比較慢,但提供了Backtrack功能。
            在分析兩種引擎的匹配過程時,Friedl指出,NFA是基于表達式的(Regex-Directed),而DFA是基于文本的(Text-Directed)。
            舉例來說,對于正則表達式 to(nite|knight|night)NFA在匹配最開始兩個字符(to)之后,剩下的三個組件(component)是 nite, knight night,于是正則引擎會依次嘗試這三個選擇分支(每次嘗試一個);而DFA在匹配最開始兩個字符之后,會將剩下的三個選擇拆分作字符,并行嘗試,也就是說,匹配 to 之后,先匹配 k 或者 n ,如果 k 不能匹配,則放棄 knigth 所在的分支,再匹配 i ,再匹配 t g ……這樣繼續下去,直到匹配結束。

            不幸的是,Friedl對匹配過程的分析,是完全錯誤的——引擎的不同,是指構建的自動機的不同,而不是匹配算法的不同!
            DFA
            引擎在任意時刻必定處于某個確定的狀態,而NFA引擎可能處于一組狀態之中的任何一個,所以,NFA引擎必須記錄所有的可能路徑(trace multiple possible routes through the NFA),NFA之所以能夠提供Backtrack的功能,原因就在這里。
            傳統的NFA匹配算法是帶回溯的深度優先搜索(backtracking depth-first search,就是上文所說的Regex-Based過程),而新的PCRE算法提供了效率更高的廣度優先搜索,可以同時保持所有可能的NFA狀態(請參考http://www.cl.cam.ac.uk/Teaching/current/RLFA/,尤其是Lecture Notessection 2.2)。

            Friedl
            的錯誤就在這里,他混淆了應用PCRE算法的NFADFA的匹配過程。
            需要指出的是,即使應用PCRE算法,NFA的速度仍然低于DFA,這是由NFA需要同時保存多種可能的性質決定的。從理論上說,如果我們不需要應用 Backtrack,完全可以從NFA構造出等價的DFA,再進行匹配,這樣能大大提高速度——代價是,DFA需要更多的空間。

            posted on 2009-09-29 13:56 肥仔 閱讀(2690) 評論(3)  編輯 收藏 引用 所屬分類: 狀態機 & 自動機 & 形式語言

            評論

            # re: NFA DFA Regex  回復  更多評論   

            可以參考我的cppblog主頁上的兩篇關于如何開發一個正則表達式引擎的文章。我不僅講了必要的理論知識,連實現的時候大多數情況下會遇到的問題也講了。
            2009-09-29 15:43 | 陳梓瀚(vczh)

            # re: NFA DFA Regex  回復  更多評論   

            因為現代化的regex實際上是不能用DFA來實現的。考慮一個例子:
            (<abc>\d+)|(<def>\d*)
            2009-09-29 15:45 | 陳梓瀚(vczh)

            # re: NFA DFA Regex  回復  更多評論   

            請問一下,你是用什么工具繪圖的?
            2011-12-22 23:33 | YorkTsai
            久久国语露脸国产精品电影| 精品亚洲综合久久中文字幕| 大香网伊人久久综合网2020| 亚洲国产精品久久久久婷婷软件| 久久久人妻精品无码一区| 亚洲国产成人久久精品99| 久久精品国产亚洲AV大全| 国产成人久久精品二区三区| 欧美精品福利视频一区二区三区久久久精品 | 97久久国产综合精品女不卡| 久久99毛片免费观看不卡| 久久男人中文字幕资源站| 亚洲AV无码久久精品狠狠爱浪潮 | 免费精品国产日韩热久久| 9久久9久久精品| 久久香蕉超碰97国产精品| 2021国内久久精品| 久久性生大片免费观看性| 久久天天躁狠狠躁夜夜avapp | 亚洲国产精品无码久久一线 | 香蕉aa三级久久毛片| 国产69精品久久久久99尤物| 久久人人爽人人爽人人片av麻烦| 99久久人妻无码精品系列| 浪潮AV色综合久久天堂| 久久99精品国产99久久6| 丁香久久婷婷国产午夜视频| 亚洲伊人久久精品影院| 久久只有这精品99| 久久久久免费视频| 久久天天躁夜夜躁狠狠| 精品水蜜桃久久久久久久| 久久91精品国产91久久麻豆| 精品熟女少妇AV免费久久| 中文字幕无码久久精品青草| 免费精品久久久久久中文字幕 | 久久精品国产亚洲AV香蕉| 亚洲国产香蕉人人爽成AV片久久| 久久国产香蕉一区精品| 精品久久国产一区二区三区香蕉| 中文字幕亚洲综合久久2|