亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Regex > 正文

正則表達式之回溯

2020-03-16 21:13:45
字體:
來源:轉載
供稿:網友
我通常在匹配一個字符串或是一組數字的時候會用到正則表達式,但很少會了解它是如何真正開始工作的?它的工作原理是什么?其實正則表達式里面的貓膩還挺多水也挺深的,有時候還不太好理解。
 
 
關于“回溯”我也是第一次接觸,對它也不算很了解。下面就把我所了解的做為一個心德記錄下來,以備查看。

我們所使用的正則表達式的匹配基礎大概分為:優先選擇最左端(最靠開頭)的匹配結果和標準的匹配量詞(*、+、?和{m, n})是匹配優先的。 

“優先選擇最左端的匹配”顧名思義就是從字符串的起始位置開始匹配直到匹配結束這是基礎;“標準匹配量詞”又分為“非確定型有窮自動機(NFA)”也可以叫做“表達式主導”;另外一種是“確定型有窮自動機(DFA)”也可以叫做“文本主導”。我們目前在JavaScript中所使用的正則表達式為“表達式主導”。表達式主導和文本主導解釋起來有些麻煩,先看來一個例子可能會清楚些。 

復制代碼代碼如下:

// 使用正則表達式匹配文本 
var reg = /to(nite|knight|night)/; 
var str = 'doing tonight'; 
reg.test(str);

在上面的這個例子中,第一個元素[t],它將會重復嘗試,直到目標字符串中找到‘t'為止。之后,就檢查緊隨其后的字符是否能由[o]匹配,如果能,就檢查下面的元素(nite|knight|night)。它的真正含義是“nite”或者“knight”或者“night”。引擎會依次嘗試這3種可能。嘗試[nite]的過程是先嘗試[n],然后[i],然后[t],最后是[e]。如果這種嘗試失敗,引擎會嘗試另一種可能,如此繼續下去,直到匹配成功或是報告失敗。表達式中的控制權在不同的元素之間轉換,所以稱為“表達式主導”。

    同樣是上面的例子“文本主導”在掃描字符串時,會記錄當前有效的所有匹配可。當引擎移動到t時,它會在當前處理的匹配可能中添加一個潛在的可能:

字符串中的位置 正則表達中的位置
……doing tonight 可能的匹配位置:/to(nite|knight|nigth)/

 

接下來掃描的每個字符,都會更新當前的可能匹配序列。繼續掃描兩個字符以后的情況是:

 

字符串中的位置 正則表達中的位置
……doing tonight 可能的匹配位置:/to(nite|knight|nigth)/

 

有效的可能匹配變為兩個(knight被淘汰出局)。掃描到g時,就只剩下一個可能匹配了。當h和t匹配完成后,引擎發現匹配已經完成,報告成功。“文本主導”是因為它掃描的字符串中的每個字符都對引擎進行了控制。

    如果想要弄明白“表達式主導”是如何工作的,那就要看一下我們今天的主題“回溯(backtracking)”?;厮菥拖袷窃谧卟砺房冢斢龅讲砺返臅r候就先在每個路口做一個標記。如果走了死路,就可以照原路返回,直到遇見之前所做過的標記,標記著還未嘗試過的道路。如果那條路也走不能,可以繼續返回,找到下一個標記,如此重復,直到找到出路,或者直到完成所有沒有嘗試過的路。

    在許多情況下,正則引擎必須在兩個(或更多)選項中做出選擇。當遇到/……x?……/時,引擎必須是否嘗試匹配X。對于/……X+……/的情況,毫無疑問,X至少嘗試匹配一次——因為加號要求必須匹配至少一次。第一個X匹配之后,此要求已經滿足,需要決定是否嘗試下一個X。如果決定進行,還要決定是否匹配第三個X,第四個X,如此繼續。每次選擇,其實就是做一個標記,用于提示此處還有另一個可能的選擇,保留起來以備用。在回溯的過程中要考慮兩個要點:哪個分支應當首先選擇?回溯的時候使用的是哪個(或者是哪些個)之前保存的分支?

    第一個問題是按下面這條重要原則來選擇的:

        如果需要在“進行嘗試”和“路過嘗試”之間選擇,對于匹配優先量詞,引擎會優先選擇“進行嘗試”,而對于忽略優先量詞,會選擇“路過嘗試”。

    第二個問題是按以下這條原則:

        距離當前最近儲存的選項就是當本地失敗強制回溯時返回的。使用的原則是LIFO(last in first out,后進先出)。

    我們先來看幾個在道路中做標記的例子:

        1、未進行回溯的匹配

            用[ab?c]來匹配“abc”。[a]匹配之后,匹配的當前狀態如下:

“abc” ab?c

            現在輪到[b?]了,正則引擎需要決定:是需要嘗試[b]呢,還是跳過?因為[?]是匹配優先的,它會嘗試匹配。但是,為了確保在這個嘗試最終失敗之后能夠恢復,引擎會把:

“abc” ab?c
            添加到備用狀態序列中。也就是說,稍后引擎可能從下面的位置繼續匹配:從正則表達式中的[b?]之后,字符串的c之前(也就是說當前的位置)匹配。這實際上就是跳過[b]的匹配,而問題容許這樣做。引擎做好標記后,就會繼續向前檢查[b]。在示例中,它能夠匹配,所以新的當前狀態變為:
“abc” ab?c

            最終的[c]也能成功匹配,所以整個匹配完成。備用狀態不再需要了,所以不再保存它們。

        2、進行了回溯的匹配

            下面要匹配的文本是“ac”,在嘗試[b]之前,一切都與之前的過程相同。顯然,這次[b]無法匹配。也就是說,對[……?]進行嘗試的路走不通了。因為有一個備用狀態,這個“局部匹配失敗”產工會導致整體匹配失敗。引擎會進行回溯,也就是說,把“當前狀態”切換為最近保存的狀態。

“ac” ab?c

            在[b]嘗試之前保存的尚未嘗試的選項。這時候,[c]可以匹配c,所以整個匹配宣告完成。

        3、不成功的匹配

            現在要匹配的文本是“abx”。在嘗試[b]以前,因為存在問號,保存了這個備用狀態:

“abx” ab?c

            [b]能夠匹配,但這條路往下卻走不通了,因為[c]無法匹配x。于是引擎會回溯到之前的狀態,“交還”b給[c]來匹配。顯然,這次測試也失敗了。如果還有其他保存的狀態,回溯會繼續進行,但是此時不存在其他狀態,在字符串中當前位置開始的整個匹配也就宣告失敗。

    目前對正則表達式的回溯只能理解這么多,以后我再慢慢補充吧!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩久久免费电影| 欧美精品999| 一区二区三区视频在线| 国产精品久久久久久久久久小说| 欧美福利视频在线观看| 日韩av免费网站| 爽爽爽爽爽爽爽成人免费观看| 91精品国产高清久久久久久| 九九热最新视频//这里只有精品| 日本免费一区二区三区视频观看| 国产成人亚洲精品| 这里只有精品视频在线| 在线观看91久久久久久| 日本高清+成人网在线观看| 日本久久久a级免费| 欧美日韩国产综合视频在线观看中文| 成人免费观看49www在线观看| 亚洲精品免费一区二区三区| 欧美成人免费va影院高清| 狠狠做深爱婷婷久久综合一区| 亚洲激情第一页| 97人人爽人人喊人人模波多| 亚洲欧美在线看| 精品国产精品三级精品av网址| 久久视频中文字幕| 亚洲三级av在线| 国产成人在线精品| 国产精品网站入口| 欧美日韩一区二区三区在线免费观看| 国产在线精品一区免费香蕉| 在线播放亚洲激情| 91中文字幕一区| 成人乱色短篇合集| 北条麻妃一区二区三区中文字幕| 色偷偷噜噜噜亚洲男人| 久久视频在线播放| 国产精品久久久久久久久男| 欧美激情高清视频| 亚洲最大福利视频网| 国产精品自拍偷拍视频| 欧美黑人性猛交| 91在线视频导航| 亚洲欧美国产高清va在线播| www.99久久热国产日韩欧美.com| 亚洲第一免费网站| 欧美一区第一页| 久久久99久久精品女同性| 欧美激情免费视频| 亚洲欧美激情精品一区二区| 亚洲女人天堂视频| 欧美国产视频一区二区| 久久精品视频网站| 久久久久亚洲精品国产| 亚洲国产欧美一区二区三区同亚洲| 国产亚洲欧洲高清一区| 97国产精品视频人人做人人爱| 亚洲最新在线视频| 精品亚洲国产成av人片传媒| 国产69精品久久久久久| 欧美成人四级hd版| 日韩在线观看免费av| 国产欧美日韩综合精品| 国自产精品手机在线观看视频| 国产精品日日做人人爱| 国产在线视频91| 最新国产精品拍自在线播放| 国产精品永久免费视频| 欧美高清在线观看| 庆余年2免费日韩剧观看大牛| 91精品国产乱码久久久久久久久| 亚洲剧情一区二区| 在线看国产精品| 97精品在线视频| 2020欧美日韩在线视频| 97超级碰碰碰| 国产精品夜间视频香蕉| 亚洲女人天堂成人av在线| 日本在线观看天堂男亚洲| www欧美日韩| 欧美日韩高清区| 日韩一区二区久久久| 自拍亚洲一区欧美另类| 国产婷婷97碰碰久久人人蜜臀| 97超视频免费观看| 欧美电影免费观看高清完整| 国产成人精品综合久久久| 亚洲精品福利视频| 色偷偷噜噜噜亚洲男人| 日韩电影在线观看中文字幕| 国产精品∨欧美精品v日韩精品| www.欧美精品一二三区| 俺也去精品视频在线观看| 欧美大片在线看免费观看| 国产精品亚洲网站| 中文国产成人精品久久一| 美日韩在线视频| 91手机视频在线观看| 亚洲xxxxx电影| 欧美黑人xxxⅹ高潮交| 亚洲精品国产精品国自产观看浪潮| 亚洲天堂免费在线| 国产网站欧美日韩免费精品在线观看| 国产91免费观看| 日韩大陆毛片av| 亚洲另类欧美自拍| 色偷偷888欧美精品久久久| 国产精品视频内| 国产91精品视频在线观看| 久久亚洲精品网站| 97人人做人人爱| 亚洲精品成a人在线观看| 成人精品一区二区三区电影免费| 91精品国产高清久久久久久久久| 日本久久久久久久| 亚洲欧美日韩另类| 色悠悠久久久久| 国产精品成人免费电影| 欧美性猛交xxxx乱大交蜜桃| 欧美老少做受xxxx高潮| 97在线观看视频| 亚洲二区在线播放视频| 国产69精品久久久久99| 亚洲日韩第一页| 国产精品视频一区二区三区四| 国产日本欧美一区| 久久成人国产精品| 亚洲天堂色网站| 尤物99国产成人精品视频| 日韩亚洲成人av在线| 亚洲女性裸体视频| 欧美精品18videosex性欧美| 亚洲免费av网址| 麻豆一区二区在线观看| 色婷婷久久av| 亚洲毛片在线免费观看| 久久天天躁狠狠躁夜夜爽蜜月| 日本免费久久高清视频| 日本一区二区三区在线播放| 精品欧美激情精品一区| 68精品久久久久久欧美| 亚洲影影院av| 欧美激情久久久| 国产一区深夜福利| 91av在线网站| 国产精品福利久久久| 欧美老少配视频| 久久激情视频久久| 亚洲性视频网址| 91在线观看免费网站| 欧美激情综合色综合啪啪五月| 亚洲在线一区二区| 亚洲欧美视频在线| 日韩成人久久久| 久久精品福利视频| 亚洲精品网址在线观看| 日韩在线观看电影| 日韩精品视频在线观看网址| 亚洲精品中文字幕女同| 中文字幕亚洲情99在线| 国产丝袜精品视频| 久久久精品免费视频| 久久99热精品这里久久精品| 亚洲国产小视频在线观看| 亚洲高清在线观看|