最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

正則基礎之 NFA引擎匹配原理

 更新時間:2009年07月24日 15:58:42   作者:  
不懂正則引擎原理的情況下,同樣可以寫出滿足需求的正則,但是不知道原理,卻很難寫出高效且沒有隱患的正則。所以對于經(jīng)常使用正則,或是有興趣深入學習正則的人,還是有必要了解一下正則引擎的匹配原理的。

1       為什么要了解引擎匹配原理

一個個音符雜亂無章的組合在一起,彈奏出的或許就是噪音,同樣的音符經(jīng)過作曲家的手,就可以譜出非常動聽的樂曲,一個演奏者同樣可以照著樂譜奏出動聽的樂曲,但他/她或許不知道該如何去改變音符的組合,使得樂曲更動聽。

作為正則的使用者也一樣,不懂正則引擎原理的情況下,同樣可以寫出滿足需求的正則,但是不知道原理,卻很難寫出高效且沒有隱患的正則。所以對于經(jīng)常使用正則,或是有興趣深入學習正則的人,還是有必要了解一下正則引擎的匹配原理的。

2       正則表達式引擎

正則引擎大體上可分為不同的兩類:DFA和NFA,而NFA又基本上可以分為傳統(tǒng)型NFA和POSIX NFA。

DFA Deterministic finite automaton 確定型有窮自動機

NFA Non-deterministic finite automaton 非確定型有窮自動機

Traditional NFA

POSIX NFA

DFA引擎因為不需要回溯,所以匹配快速,但不支持捕獲組,所以也就不支持反向引用和$number這種引用方式,目前使用DFA引擎的語言和工具主要有awk、egrep 和 lex。

POSIX NFA主要指符合POSIX標準的NFA引擎,它的特點主要是提供longest-leftmost匹配,也就是在找到最左側最長匹配之前,它將繼續(xù)回溯。同DFA一樣,非貪婪模式或者說忽略優(yōu)先量詞對于POSIX NFA同樣是沒有意義的。

大多數(shù)語言和工具使用的是傳統(tǒng)型的NFA引擎,它有一些DFA不支持的特性:

  捕獲組、反向引用和$number引用方式;

  環(huán)視(Lookaround,(?<=…)、(?<!…)、(?=…)、(?!…)),或者有的有文章叫做預搜索;

  忽略優(yōu)化量詞(??、*?、+?、{m,n}?、{m,}?),或者有的文章叫做非貪婪模式;

  占有優(yōu)先量詞(?+、*+、++、{m,n}+、{m,}+,目前僅Java和PCRE支持),固化分組(?>…)。

引擎間的區(qū)別不是本文的重點,僅做簡要的介紹,有興趣的可參考相關文獻。

3       預備知識

3.1     字符串組成

對于字符串“abc”而言,包括三個字符和四個位置。

3.2     占有字符和零寬度

正則表達式匹配過程中,如果子表達式匹配到的是字符內(nèi)容,而非位置,并被保存到最終的匹配結果中,那么就認為這個子表達式是占有字符的;如果子表達式匹配的僅僅是位置,或者匹配的內(nèi)容并不保存到最終的匹配結果中,那么就認為這個子表達式是零寬度的。

占有字符是互斥的,零寬度是非互斥的。也就是一個字符,同一時間只能由一個子表達式匹配,而一個位置,卻可以同時由多個零寬度的子表達式匹配。

3.3     控制權和傳動

正則的匹配過程,通常情況下都是由一個子表達式(可能為一個普通字符、元字符或元字符序列組成)取得控制權,從字符串的某一位置開始嘗試匹配,一個子表達式開始嘗試匹配的位置,是從前一子表達匹配成功的結束位置開始的。如正則表達式:

(子表達式一)(子表達式二)

假設(子表達式一)為零寬度表達式,由于它匹配開始和結束的位置是同一個,如位置0,那么(子表達式二)是從位置0開始嘗試匹配的。

假設(子表達式一)為占有字符的表達式,由于它匹配開始和結束的位置不是同一個,如匹配成功開始于位置0,結束于位置2,那么(子表達式二)是從位置2開始嘗試匹配的。

而對于整個表達式來說,通常是由字符串位置0開始嘗試匹配的。如果在位置0開始的嘗試,匹配到字符串某一位置時整個表達式匹配失敗,那么引擎會使正則向前傳動,整個表達式從位置1開始重新嘗試匹配,依此類推,直到報告匹配成功或嘗試到最后一個位置后報告匹配失敗。

4       正則表達式簡單匹本過程

4.1     基礎匹配過程

 

源字符串:abc

正則表達式:abc

匹配過程:

首先由字符“a”取得控制權,從位置0開始匹配,由“a”來匹配“a”,匹配成功,控制權交給字符“b”;由于“a”已被“a”匹配,所以“b”從位置1開始嘗試匹配,由“b”來匹配“b”,匹配成功,控制權交給“c”;由“c”來匹配“c”,匹配成功。

此時正則表達式匹配完成,報告匹配成功。匹配結果為“abc”,開始位置為0,結束位置為3。

 

4.2     含有匹配優(yōu)先量詞的匹配過程——匹配成功(一)

源字符串:abc

正則表達式:ab?c

量詞“?”屬于匹配優(yōu)先量詞,在可匹配可不匹配時,會先選擇嘗試匹配,只有這種選擇會使整個表達式無法匹配成功時,才會嘗試讓出匹配到的內(nèi)容。這里的量詞“?”是用來修飾字符“b”的,所以“b?”是一個整體。

匹配過程:

首先由字符“a”取得控制權,從位置0開始匹配,由“a”來匹配“a”,匹配成功,控制權交給字符“b?”;由于“?”是匹配優(yōu)先量詞,所以會先嘗試進行匹配,由“b?”來匹配“b”,匹配成功,控制權交給“c”,同時記錄一個備選狀態(tài);由“c”來匹配“c”,匹配成功。記錄的備選狀態(tài)丟棄。

此時正則表達式匹配完成,報告匹配成功。匹配結果為“abc”,開始位置為0,結束位置為3。

4.3     含有匹配優(yōu)先量詞的匹配過程——匹配成功(二)

源字符串:ac

正則表達式:ab?c

匹配過程:

首先由字符“a”取得控制權,從位置0開始匹配,由“a”來匹配“a”,匹配成功,控制權交給字符“b?”;先嘗試進行匹配,由“b?”來匹配“c”,同時記錄一個備選狀態(tài),匹配失敗,此時進行回溯,找到備選狀態(tài),“b?”忽略匹配,讓出控制權,把控制權交給“c”;由“c”來匹配“c”,匹配成功。

此時正則表達式匹配完成,報告匹配成功。匹配結果為“ac”,開始位置為0,結束位置為2。其中“b?”不匹配任何內(nèi)容。

4.4     含有匹配優(yōu)先量詞的匹配過程——匹配失敗

源字符串:abd

正則表達式:ab?c

匹配過程:

首先由字符“a”取得控制權,從位置0開始匹配,由“a”來匹配“a”,匹配成功,控制權交給字符“b?”;先嘗試進行匹配,由“b?”來匹配“b”,同時記錄一個備選狀態(tài),匹配成功,控制權交給“c”;由“c”來匹配“d”,匹配失敗,此時進行回溯,找到記錄的備選狀態(tài),“b?”忽略匹配,即“b?”不匹配“b”,讓出控制權,把控制權交給“c”;由“c”來匹配“b”,匹配失敗。此時第一輪匹配嘗試失敗。

正則引擎使正則向前傳動,由位置1開始嘗試匹配,由“a”來匹配“b”,匹配失敗,沒有備選狀態(tài),第二輪匹配嘗試失敗。

繼續(xù)向前傳動,直到在位置3嘗試匹配失敗,匹配結束。此時報告整個表達式匹配失敗。

4.5     含有忽略優(yōu)先量詞的匹配過程——匹配成功

源字符串:abc

正則表達式:ab??c

量詞“??”屬于忽略優(yōu)先量詞,在可匹配可不匹配時,會先選擇不匹配,只有這種選擇會使整個表達式無法匹配成功時,才會嘗試進行匹配。這里的量詞“??”是用來修飾字符“b”的,所以“b??”是一個整體。

匹配過程:

首先由字符“a”取得控制權,從位置0開始匹配,由“a”來匹配“a”,匹配成功,控制權交給字符“b??”;先嘗試忽略匹配,即“b??”不進行匹配,同時記錄一個備選狀態(tài),控制權交給“c”;由“c”來匹配“b”,匹配失敗,此時進行回溯,找到記錄的備選狀態(tài),“b??”嘗試匹配,即“b??”來匹配“b”,匹配成功,把控制權交給“c”;由“c”來匹配“c”,匹配成功。

此時正則表達式匹配完成,報告匹配成功。匹配結果為“abc”,開始位置為0,結束位置為3。其中“b??”匹配字符“b”。

4.6     零寬度匹配過程

源字符串:a12

正則表達式:^(?=[a-z])[a-z0-9]+$

元字符“^”和“$”匹配的只是位置,順序環(huán)視“(?=[a-z])”只進行匹配,并不占有字符,也不將匹配的內(nèi)容保存到最終的匹配結果,所以都是零寬度的。

這個正則的意義就是匹配由字母和數(shù)字組成的,第一個字符是字母的字符串。

匹配過程:

首先由元字符“^”取得控制權,從位置0開始匹配,“^”匹配的就是開始位置“位置0”,匹配成功,控制權交給順序環(huán)視“(?=[a-z])”;

(?=[a-z])”要求它所在位置右側必須是字母才能匹配成功,零寬度的子表達式之間是不互斥的,即同一個位置可以同時由多個零寬度子表達式匹配,所以它也是從位置0嘗試進行匹配,位置0的右側是字符“a”,符合要求,匹配成功,控制權交給“[a-z0-9]+”;

因為“(?=[a-z])”只進行匹配,并不將匹配到的內(nèi)容保存到最后結果,并且“(?=[a-z])”匹配成功的位置是位置0,所以“[a-z0-9]+”也是從位置0開始嘗試匹配的,“[a-z0-9]+”首先嘗試匹配“a”,匹配成功,繼續(xù)嘗試匹配,可以成功匹配接下來的“1”和“2”,此時已經(jīng)匹配到位置3,位置3的右側已沒有字符,這時會把控制權交給“$”;

元字符“$”從位置3開始嘗試匹配,它匹配的是結束位置,也就是“位置3”,匹配成功。

此時正則表達式匹配完成,報告匹配成功。匹配結果為“a12”,開始位置為0,結束位置為3。其中“^”匹配位置0,“(?=[a-z])”匹配位置0,“[a-z0-9]+”匹配字符串“a12”,“$”匹配位置3。

相關文章

  • 正則表達式中的

    正則表達式中的"g"是什么意思附件參數(shù)g的用法

    為了能夠便于大家對正則表達式有一個更為綜合和深刻的認識,我將一些關鍵點和容易犯糊涂的地方再系統(tǒng)總結一下
    2014-07-07
  • 正則表達式學習教程之回溯引用backreference詳解

    正則表達式學習教程之回溯引用backreference詳解

    這篇文章主要介紹了正則表達式學習教程之回溯引用backreference,結合實例形式詳細分析了回溯引用的概念、功能及實現(xiàn)技巧,需要的朋友可以參考下
    2017-01-01
  • 正則表達式RegExp語法與用法詳解

    正則表達式RegExp語法與用法詳解

    正則表達式是一個描述字符模式的對象,當檢索某個文本時,可以使用一種模式來描述要檢索的內(nèi)容,RegExp就是這種模式,下面這篇文章主要給大家介紹了關于正則表達式RegExp語法與用法的相關資料,需要的朋友可以參考下
    2022-10-10
  • ES9的新特性之正則表達式RegExp詳解

    ES9的新特性之正則表達式RegExp詳解

    這篇文章主要介紹了ES9的新特性之正則表達式RegExp詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Java/Js下使用正則表達式匹配嵌套Html標簽

    Java/Js下使用正則表達式匹配嵌套Html標簽

    以前寫過一篇文章講解如何使用正則表達式完美解決Html嵌套標簽的匹配問題(使用正則表達式匹配嵌套Html標簽),但是里頭用到了平衡組這樣的高級特性,貌似只有DotNet還有Perl正則引擎支持,因此通用性不高。
    2010-08-08
  • 幾個小例子教你如何實現(xiàn)正則表達式highlight高亮

    幾個小例子教你如何實現(xiàn)正則表達式highlight高亮

    正則表達式,用起來還是挺方便的。正則技能,你值得擁有??!
    2014-05-05
  • UBB 轉換函數(shù)演示 (經(jīng)典論壇)

    UBB 轉換函數(shù)演示 (經(jīng)典論壇)

    [綠色]UBB 轉換函數(shù)演示 (經(jīng)典論壇)...
    2006-08-08
  • 比較常用證件正則表達式驗證大全

    比較常用證件正則表達式驗證大全

    最近做項目,有項目需求需要對各種常用的證件進行驗證。而港澳通行證,臺灣通行證,護照這些證件,在網(wǎng)上沒有搜到正則驗證的方法,后來經(jīng)過一番折騰,結合validator這個驗證插件寫了一些代碼,在此分享給大家,需要的朋友可以參考下
    2015-10-10
  • Java正則表達式使用

    Java正則表達式使用

    本篇文章主要給大家介紹java在正則表達式的使用,本篇文章給大家主要介紹應用點在抓取網(wǎng)頁中的email地址和代碼統(tǒng)計,感興趣的朋友一起看看吧
    2015-09-09
  • 學習網(wǎng)址

    學習網(wǎng)址

    學習網(wǎng)址...
    2006-06-06

最新評論

阜新市| 会昌县| 建始县| 克拉玛依市| 昆明市| 罗定市| 庐江县| 黑龙江省| 凌源市| 彭州市| 和静县| 昌图县| 德保县| 河池市| 永靖县| 徐州市| 仙桃市| 夏邑县| 龙州县| 图木舒克市| 图木舒克市| 卓资县| 五台县| 临汾市| 都安| 保山市| 金秀| 剑阁县| 通山县| 铁岭县| 三台县| 浙江省| 苍溪县| 梁山县| 中宁县| 乳山市| 汉源县| 化德县| 黄山市| 东乡族自治县| 山阳县|