正则表达式的环视深度剖析
文章目錄
- 一、環(huán)視基礎(chǔ)
- 二、順序環(huán)視匹配過程
- (一)順序肯定環(huán)視匹配過程
- (二)順序否定環(huán)視匹配過程
- 三、逆序環(huán)視匹配過程
- (一)逆序環(huán)視基礎(chǔ)
- (二)逆序肯定環(huán)視匹配過程
- 1. 逆序表達(dá)式的長度固定,如何匹配
- 2. 逆序表達(dá)式的長度不固定,如何匹配
- (1)匹配開始位置不確定,匹配結(jié)束位置確定
- (2)匹配開始位置確定,匹配結(jié)束位置不確定
- (三)逆序否定環(huán)視匹配過程
- 1. 逆序表達(dá)式的長度固定,如何匹配
- (1)匹配起始位置不確定,匹配結(jié)束位置確定
- (2)匹配起始位置確定,匹配結(jié)束位置不確定
- 2. 逆序表達(dá)式的長度不固定,如何匹配
一、環(huán)視基礎(chǔ)
環(huán)視只進(jìn)行子表達(dá)式的匹配,不占有字符,匹配到的內(nèi)容不保存到最終的匹配結(jié)果,是零寬度的。環(huán)視匹配的最終結(jié)果就是一個(gè)位置。
環(huán)視的作用相當(dāng)于對(duì)所在位置加了一個(gè)附加條件,只有滿足這個(gè)條件,環(huán)視子表達(dá)式才能匹配成功。
環(huán)視按照方向劃分有順序和逆序兩種,按照是否匹配有肯定和否定兩種,組合起來就有四種環(huán)視。順序環(huán)視相當(dāng)于在當(dāng)前位置右側(cè)附加一個(gè)條件,而逆序環(huán)視相當(dāng)于在當(dāng)前位置左側(cè)附加一個(gè)條件。
| (?<=Expression) | 逆序肯定環(huán)視,表示所在位置左側(cè)能夠匹配 Expression |
| (?<!Expression) | 逆序否定環(huán)視,表示所在位置左側(cè)不能匹配 Expression |
| (?=Expression) | 順序肯定環(huán)視,表示所在位置右側(cè)能夠匹配 Expression |
| (?!Expression) | 順序否定環(huán)視,表示所在位置右側(cè)不能匹配 Expression |
環(huán)視是正則中的一個(gè)難點(diǎn),對(duì)于環(huán)視的理解,可以從應(yīng)用和原理兩個(gè)角度理解,如果想理解得更清晰、深入一些,還是從原理的角度理解好一些,正則匹配基本原理參考《NFA引擎匹配原理》。
上面提到環(huán)視相當(dāng)于對(duì)“所在位置”附加了一個(gè)條件,環(huán)視的難點(diǎn)在于找到這個(gè)“位置”,這一點(diǎn)解決了,環(huán)視也就沒什么秘密可言了。
對(duì)于順序肯定環(huán)視(?=Expression)來說,當(dāng)子表達(dá)式Expression匹配成功時(shí),(?=Expression)匹配成功,并報(bào)告(?=Expression)匹配當(dāng)前位置成功。
對(duì)于順序否定環(huán)視(?!Expression)來說,當(dāng)子表達(dá)式Expression匹配成功時(shí),(?!Expression)匹配失敗;當(dāng)子表達(dá)式Expression匹配失敗時(shí),(?!Expression)匹配成功,并報(bào)告(?!Expression)匹配當(dāng)前位置成功。
二、順序環(huán)視匹配過程
(一)順序肯定環(huán)視匹配過程
順序肯定環(huán)視的例子已在《NFA引擎匹配原理》中講解過了,請(qǐng)移步參考。
(二)順序否定環(huán)視匹配過程
源字符串:aa<p>one</p>bb<div>two</div>cc
正則表達(dá)式:<(?!/?p\b)[^>]+>
這個(gè)正則的意義就是匹配除 <p> 或 </p>之外的其余標(biāo)簽。/? 表示匹配正斜杠 0 次或 1 次;\b 表示匹配字符邊界。
首先由表達(dá)式的字符 < 取得控制權(quán),從源字符串位置 0 開始匹配,由于 < 匹配 a 失敗,在位置 0 處整個(gè)表達(dá)式匹配失敗,第一次迭代匹配失敗,正則引擎向前傳動(dòng),由位置 1 處開始嘗試第二次迭代匹配。
重復(fù)以上過程,直到位置 2,表達(dá)式的字符 < 匹配源字符串的字符 < 成功,控制權(quán)交給 (?!/?p\b);(?!/?p\b) 子表達(dá)式取得控制權(quán)后,進(jìn)行內(nèi)部子表達(dá)式的匹配。首先由 /? 取得控制權(quán),嘗試匹配 p 失敗,進(jìn)行回溯,不匹配,控制權(quán)交給 p;由 p 來嘗試匹配 p,匹配成功,控制權(quán)交給 \b;由 \b 來嘗試匹配位置 4,匹配成功。此時(shí)子表達(dá)式匹配完成,/?p\b 匹配成功,那么環(huán)視表達(dá)式 (?!/?p\b) 就匹配失敗。在位置 2 處整個(gè)表達(dá)式匹配失敗,新一輪迭代匹配失敗,正則引擎向前傳動(dòng),由位置 3 處開始嘗試下一輪迭代匹配。
在位置 8 處也會(huì)遇到一輪 /?p\b 匹配 /p 成功,而導(dǎo)致環(huán)視表達(dá)式 (?!/?p\b) 匹配失敗,從而導(dǎo)致整個(gè)表達(dá)式匹配失敗的過程。
重復(fù)以上過程,直到位置 14,< 匹配 < 成功,控制權(quán)交給 (?!/?p\b);/? 嘗試匹配 d 失敗,進(jìn)行回溯,不匹配,控制權(quán)交給 p;由 p 來嘗試匹配 d,匹配失敗,已經(jīng)沒有備選狀態(tài)可供回溯,匹配失敗。此時(shí)子表達(dá)式匹配完成,/?p\b 匹配失敗,那么環(huán)視表達(dá)式 (?!/?p\b) 就匹配成功。匹配的結(jié)果是位置15,然后控制權(quán)交給 [^>]+;由 [^>]+ 從位置 15 進(jìn)行嘗試匹配,可以成功匹配到 div,控制權(quán)交給 >;由 >來匹配 >,匹配成功。此時(shí)正則表達(dá)式匹配完成,報(bào)告匹配成功。
匹配結(jié)果為 <div>,開始位置為 14,結(jié)束位置為 19。其中 < 匹配 <,(?!/?p\b) 匹配位置 15,[^>]+ 匹配字符串 div,> 匹配 >。
三、逆序環(huán)視匹配過程
(一)逆序環(huán)視基礎(chǔ)
對(duì)于逆序肯定環(huán)視 (?<=Expression) 來說,當(dāng)子表達(dá)式 Expression 匹配成功時(shí),(?<=Expression) 匹配成功,并報(bào)告 (?<=Expression) 匹配當(dāng)前位置成功。
對(duì)于逆序否定環(huán)視 (?<!Expression) 來說,當(dāng)子表達(dá)式 Expression 匹配成功時(shí),(?<!Expression) 匹配失敗;當(dāng)子表達(dá)式 Expression 匹配失敗時(shí),(?<!Expression)匹配成功,并報(bào)告(?<!Expression)匹配當(dāng)前位置成功;
順序環(huán)視相當(dāng)于在當(dāng)前位置右側(cè)附加一個(gè)條件,所以它的匹配嘗試是從當(dāng)前位置開始的,然后向右嘗試匹配,直到某一位置使得匹配成功或失敗為止。而逆序環(huán)視的特殊處在于,它相當(dāng)于在當(dāng)前位置左側(cè)附加一個(gè)條件,所以它不是在當(dāng)前位置開始嘗試匹配的,而是從當(dāng)前位置左側(cè)某一位置開始,匹配到當(dāng)前位置為止,報(bào)告匹配成功或失敗。
順序環(huán)視嘗試匹配的起點(diǎn)是確定的,就是當(dāng)前位置,而匹配的終點(diǎn)是不確定的。逆序環(huán)視匹配的起點(diǎn)是不確定的,是當(dāng)前位置左側(cè)某一位置,而匹配的終點(diǎn)是確定的,就是當(dāng)前位置。
所以順序環(huán)視相對(duì)是簡單的,而逆序環(huán)視相對(duì)是復(fù)雜的。這也就是為什么大多數(shù)語言和工具都提供了對(duì)順序環(huán)視的支持,而只有少數(shù)語言提供了對(duì)逆序環(huán)視支持的原因。
JavaScript 中只支持順序環(huán)視,不支持逆序環(huán)視。
Java 中雖然順序環(huán)視和逆序環(huán)視都支持,但是逆序環(huán)視只支持長度確定的表達(dá)式,逆序環(huán)視中量詞只支持“?”,不支持其它長度不定的量詞。長度確定時(shí),引擎可以向左查找固定長度的位置作為起點(diǎn)開始嘗試匹配,而如果長度不確定時(shí),就要從當(dāng)前位置向左逐個(gè)位置開始嘗試匹配,不成功則回溯,再向左側(cè)位置進(jìn)行嘗試匹配,然后重復(fù)以上過程,直到匹配成功,或是嘗試到位置0處以后,報(bào)告匹配失敗,處理的復(fù)雜度是顯而易見的。
目前只有.NET中支持不確定長度的逆序環(huán)視。
(二)逆序肯定環(huán)視匹配過程
1. 逆序表達(dá)式的長度固定,如何匹配
源字符串:<div>a test</div>
正則表達(dá)式:(?<=<div>)[^<]+(?=</div>)
這個(gè)正則的意義就是匹配 <div> 和 </div> 標(biāo)簽之間的內(nèi)容,而不包括 <div> 和 </div>標(biāo)簽本身。
首先由逆序肯定環(huán)視表達(dá)式 (?<=<div>) 取得控制權(quán),從位置 0 開始匹配,由于逆序肯定環(huán)視表達(dá)式中的子表達(dá)式 <div> 長度是 5,所以正則引擎會(huì)從當(dāng)前位置向左側(cè)查找 5 個(gè)字符來匹配,可是當(dāng)前位置是 0,左側(cè)沒有任何內(nèi)容,所以子表達(dá)式 <div> 必然匹配失敗,從而逆序肯定環(huán)視表達(dá)式 (?<=<div>) 匹配失敗,則整個(gè)正則表達(dá)式在字符串的位置 0 處匹配失敗,即正則表達(dá)式的第 1 輪迭代匹配失敗。
正則引擎向前傳動(dòng),由位置 1 處開始嘗試第 2 次迭代匹配,由于位置左側(cè)的字符數(shù)量不足,所以也是匹配失敗。直到傳動(dòng)到位置 5,正則引擎向左查找到 5 個(gè)字符,(?<=<div>) 取得控制權(quán)后,由位置 0 開始向右逐個(gè)字符匹配,結(jié)果子表達(dá)式 <div> 匹配字符串 <div> 成功,從而整個(gè)逆序肯定環(huán)視表達(dá)式 (?<=<div>) 匹配成功,匹配成功的位置是 5,控制權(quán)交給下一個(gè)子表達(dá)式 [^<]+;[^<]+ 從位置 5 向右開始逐個(gè)字符匹配,匹配字符串 a test 成功,控制權(quán)交給順序肯定環(huán)視表達(dá)式 (?=</div>);由 </div> 匹配 </div> 成功,從而順序肯定環(huán)視表達(dá)式 (?=</div>) 匹配成功,位置 11 匹配成功。
此時(shí)正則表達(dá)式匹配完成,報(bào)告匹配成功。匹配到的字符串為 a test,匹配開始位置為 5,匹配結(jié)束位置為 11。其中 (?<=<div>) 匹配位置 5,[^<]+ 匹配字符串 a test,(?=</div>) 匹配位置 11。
疑問:
逆序環(huán)視表達(dá)式的匹配是如何確定匹配開始位置的?如果是按照表達(dá)式的長度向左查找對(duì)應(yīng)數(shù)量的字符數(shù),從而確定匹配起點(diǎn),那么當(dāng)前位置左側(cè)的字符數(shù)量不足時(shí),匹配起點(diǎn)位置就無法確定,也就不會(huì)逐個(gè)字符去匹配了,因?yàn)殚L度都不同,匹配結(jié)果肯定是失敗的。猜測,大概率是按逆序環(huán)視子表達(dá)式的長度(或者最小長度)來確定起點(diǎn),如果字符數(shù)不足,就沒有必要逐個(gè)字符去匹配,因?yàn)檫@是多余的,匹配結(jié)果肯定是失敗的。
2. 逆序表達(dá)式的長度不固定,如何匹配
源字符串:<div id=“test1”>a test</div>
正則表達(dá)式:(?<=<div[^>]*>)[^<]+(?=</div>)
(1)匹配開始位置不確定,匹配結(jié)束位置確定
注:我不認(rèn)可這樣的匹配邏輯。
首先由“(?<=<div[^>]*>)”取得控制權(quán),由位置 0 開始匹配,由于“<div[^>]*>”的長度不固定,可能會(huì)由逆序環(huán)視表達(dá)式的第 1 個(gè)字符從當(dāng)前位置向左逐字符查找(這個(gè)可能性不大,因?yàn)樘盗?#xff01;);有可能是先計(jì)算逆序表達(dá)式最小長度,然后在當(dāng)前位置向前查找初始的匹配起點(diǎn)位置。在這里“<div[^>]*>”至少需要 5 個(gè)字符,所以由當(dāng)前位置向左查找 5 個(gè)字符,然后再從左到右的方向,從這 5 個(gè)字符的第 1 個(gè)字符開始嘗試匹配,但是由于此時(shí)位于位置 0處,前面沒有任何字符,所以嘗試匹配失敗。
正則引擎?zhèn)鲃?dòng)裝置向右傳動(dòng),由位置 1 處開始嘗試匹配,同樣因?yàn)樽髠?cè)的字符數(shù)不足,所以直接匹配失敗,直到位置 5 處,向左查找 5 個(gè)字符,滿足條件,此時(shí)把控制權(quán)交給“(?<=<div[^>]*>)”中的子表達(dá)式“<div[^>]*>”。“<div[^>]*>”取得控制權(quán)后,由位置 0 處開始向右嘗試匹配,由于正則都是逐字符進(jìn)行匹配的,所以這時(shí)會(huì)把控制權(quán)交給“<div[^>]*>”中的“<”,由“<”嘗試匹配字符串中的“<”,匹配成功,接下來由“d”嘗試匹配字符串中的“d”,匹配成功,同樣的過程,由“<div[^>]*”匹配位置 0 到位置 5 之間的“<div ”成功,其中“[^>]*”在匹配“<div ”中的空格時(shí)會(huì)記錄可供回溯的狀態(tài)的,此時(shí)控制權(quán)交給“>”,由于已沒有任何字符可供匹配,所以“>”匹配失敗,此時(shí)進(jìn)行回溯,由“[^>]*”讓出已匹配的空格給“>”進(jìn)行匹配,同樣匹配失敗,此時(shí)已沒有可供回溯的狀態(tài),所以這一輪迭代匹配失敗。
正則引擎?zhèn)鲃?dòng)裝置向右傳動(dòng),由位置 6 處開始嘗試匹配,同樣匹配失敗,直到位置 16 處,此時(shí)的當(dāng)前位置指的就是位置 16,向左查找到 5 個(gè)字符,把控制權(quán)交給“(?<=<div[^>]*>)”中的子表達(dá)式“<div[^>]*>”。“<div[^>]*>”取得控制權(quán)后,由位置 11 處開始向右嘗試匹配, “<div[^>]*>”中的“<”嘗試匹配字符串中的“s”,匹配失敗;繼續(xù)向左嘗試,在位置 10 處由“<”嘗試匹配字符串中的“e”,也匹配失敗。同樣的過程,直到嘗試到位置 0 處,最后“<div[^>]*>”以位置 0 作為匹配起點(diǎn),向右匹配,結(jié)果成功匹配到“<div id=“test1”>”,此時(shí)“(?<=<div[^>]*>)”匹配成功,控制權(quán)交給“[^>]+”,繼續(xù)進(jìn)行下面的匹配…
注:我認(rèn)為這樣的匹配規(guī)則是錯(cuò)誤的,因?yàn)椤?font color="#e36c0a"><div[^>]*>”中的“<”匹配失敗后往左嘗試匹配,這樣的做法很不合理,為什么?假設(shè)“<”繼續(xù)向左嘗試匹配,最后匹配成功了,控制權(quán)交個(gè)下個(gè)表達(dá)式,而該表達(dá)式匹配失敗了,“<”會(huì)繼續(xù)向左嘗試匹配,可能又匹配成功了,但是下個(gè)表達(dá)式又匹配失敗,這樣的匹配邏輯肯定不對(duì)!!!
(2)匹配開始位置確定,匹配結(jié)束位置不確定
注:這個(gè)更符合逆序的概念,也更加合理,我認(rèn)可這種匹配邏輯!
源字符串:<div>a test</div>
正則表達(dá)式:(?<=<div>)[^<]+(?=</div>)
“(?<=<div>)”獲得控制權(quán),從源字符串位置 0 開始向左匹配,首先“>” 去匹配,但是位置 0 左側(cè)沒有字符,所以匹配失敗,第 1 次迭代匹配失敗;接著正則引擎指針向右移動(dòng),“>” 去匹配字符串的字符“<”,匹配失敗,第 2 次迭代匹配失敗。
重復(fù)上述過程,直到位置 5,子表達(dá)式“<div>”中的“>” 去匹配位置 5 左邊的第 1 個(gè)字符“>”,匹配成功;子表達(dá)式“<div>”中的“v”去匹配位置 5 左邊第 2 個(gè)字符“v”,匹配成功…,最后子表達(dá)式“<div>”成功匹配位置 5 左邊的字符串“<div>”,那么說明逆序肯定環(huán)視表達(dá)式“(?<=<div>)”匹配成功,即成功匹配位置 5;接著控制權(quán)給表達(dá)式“[^<]+”,該表達(dá)式從位置 5 開始向右逐個(gè)字符匹配,最后成功匹配到字符串“a test”,接著把控制權(quán)交個(gè)子表達(dá)式“(?=</div>)”,由它去驗(yàn)證字符串“a test”的結(jié)尾位置 11 是否符合正則式的要求,結(jié)果“(?=</div>)”成功匹配到了字符串“a test”后面的字符串“</div>”,說明字符串“a test”的結(jié)尾位置 11 符合要求,后續(xù)沒有子表達(dá)式了,說明正則表達(dá)式迭代匹配成功 1 次,成功匹配到字符串“a test”。接著從位置 11 開始下次迭代匹配…
后面重復(fù)上述的過程,直到正則引擎的指針移到字符串的結(jié)尾處,則停止迭代匹配。
(三)逆序否定環(huán)視匹配過程
源字符串:adf<B>BerBilBlon<B>Ssdfefe</B>dfee
正則表達(dá)式:(?<!<B>)B
1. 逆序表達(dá)式的長度固定,如何匹配
(1)匹配起始位置不確定,匹配結(jié)束位置確定
當(dāng)前位置是匹配終點(diǎn),匹配起點(diǎn)在當(dāng)前位置的左側(cè),最終的匹配起點(diǎn)是不確定的,初始的匹配起點(diǎn)可以根據(jù)逆序表達(dá)式的長度來查找。
注:我認(rèn)為這樣的匹配邏輯是錯(cuò)誤的,不認(rèn)可
首先由“(?<!<B>)”的子表達(dá)式“<B>”取得控制權(quán),由位置 0 開始嘗匹配,由于“<B>”的長度固定為 3,所以會(huì)從當(dāng)前位置向左查找 3個(gè)字符,但是由于此時(shí)位于位置 0 處,前面沒有任何字符,所以直接匹配失敗,“<B>”匹配失敗,那么整個(gè)逆序否定環(huán)視表達(dá)式“(?<!<B>)”則匹配成功,所以位置 0 滿足逆序否定環(huán)視表達(dá)式“(?<!<B>)”,那么控制權(quán)就傳給了“B”,由“B”從位置 0 開始向右匹配字符,于是“B”就去匹配字符串中的“a”,結(jié)果匹配失敗,那么第 1 次迭代匹配失敗。
正則引擎?zhèn)鲃?dòng)裝置向右傳動(dòng),你可以理解為有個(gè)指針的東西向右移動(dòng),此時(shí)指針來到位置 1 處,由位置 1 處向左查找 3 個(gè)字符,但是前面只有 1 個(gè)字符 a,所以同樣和“<B>”匹配失敗,則整個(gè)逆序否定環(huán)視表達(dá)式“(?<!<B>)”匹配成功,控制權(quán)傳給“B”,由“B”從位置 1 開始向右匹配字符,于是“B”就去匹配字符串中的“d”,結(jié)果匹配失敗,那么第 2 次迭代匹配失敗。
直到位置 3 處,向左查找到 3 個(gè)字符串“abc”,字符數(shù)滿足條件,此時(shí)“(?<!<B>)”中的子表達(dá)式“<B>”獲得控制權(quán)。“<B>”取得控制權(quán)后,由位置 0 處開始向右逐個(gè)字符匹配字符串“abc”,既然是逐字符進(jìn)行匹配的,所以這時(shí)會(huì)把控制權(quán)交給“<B>”中的“<”,由“<”嘗試匹配字符串中的“a”,匹配失敗,那么“<B>”就和字符串“abc”匹配失敗,則整個(gè)逆序否定環(huán)視表達(dá)式“(?<!<B>)”匹配成功,控制權(quán)傳給“B”,由“B”從位置 3 開始向右匹配字符,于是“B”就去匹配字符串中的“<”,結(jié)果匹配失敗,那么第 4 次迭代匹配失敗。
正則引擎的傳動(dòng)指針繼續(xù)向右移動(dòng),此時(shí)來到了位置 4,那么正則引擎向左查找 3 個(gè)字符來匹配,查找到的字符串就是“df<”,接著“<B>”獲得控制權(quán),從位置 1 開始向右逐個(gè)字符匹配,那么首先由“<B>”中的“<”去匹配字符“d”,匹配失敗,那么整個(gè)逆序否定環(huán)視表達(dá)式“(?<!<B>)”匹配成功,控制權(quán)傳給“B”,由“B”從位置 4 開始向右匹配字符,于是“B”就去匹配位置 4 后面的“B”,結(jié)果匹配成功。
重復(fù)上述的過程直到正則引擎的指針移到字符串結(jié)尾才結(jié)束迭代匹配。
最后匹配到的“B”,如下所示(高亮部分):
(2)匹配起始位置確定,匹配結(jié)束位置不確定
當(dāng)前位置是匹配起點(diǎn),逆序環(huán)視是從當(dāng)前位置向左開始匹配的,匹配終點(diǎn)在當(dāng)前位置的左側(cè)。不少人認(rèn)為應(yīng)該是這樣的匹配規(guī)則,因?yàn)楦夏嫘虻母拍睢N乙仓С诌@個(gè)匹配邏輯。
注:需要明確的一點(diǎn),無論是什么樣的正則表達(dá)式,都是要從字符串的位置 0 處開始嘗試匹配的,這點(diǎn)沒有變。
逆序否定環(huán)視表達(dá)式“(?<!<B>)B”中的“<B>”先獲得控制權(quán),因?yàn)槠ヅ鋸挠业阶?#xff0c;所以子表達(dá)式“<B>”中的“>”會(huì)先獲得控制權(quán),去匹配字符串當(dāng)前位置左邊的第 1 個(gè)字符,不過當(dāng)前位置是 0,所以左側(cè)沒有字符,固然匹配失敗,既然“<B>”匹配失敗,那么整個(gè)逆序否定環(huán)視表達(dá)式“(?<!<B>)B”就匹配成功,也就是說位置 0 是匹配成功的,位置 0 是滿足逆序否定環(huán)視表達(dá)式的,于是控制權(quán)交給“B”,由“B”從字符串位置 0 開始向右匹配字符,顯然“B”匹配“a”是失敗的,因此整個(gè)正則表達(dá)式的第 1 次迭代匹配失敗。
重復(fù)上述的過程,直到位置 4,“<B>”從位置 4 開始向左逐個(gè)字符匹配,首先由“>”匹配位置 4 左邊的第 1 個(gè)字符“<”,結(jié)果匹配失敗,于是整個(gè)逆序否定環(huán)視表達(dá)式“(?<!<B>)B”匹配成功,也就是說位置 4 匹配成功,控制權(quán)交個(gè)了“B”,由“B”從位置 4 開始向右匹配字符,顯示“B”與字符“B”匹配成功。
重復(fù)上述過程,直到正則引擎的指針移到位置 6 時(shí),“<B>”逐個(gè)字符匹配位置 6 左側(cè)的字符,首先“<B>”中的“>”先去匹配位置 6 左邊的第 1 個(gè)字符“>”,匹配成功;接著“<B>”中的“B”去匹配位置 6 左邊的第 2 個(gè)字符“B”,也匹配成功;接著“<B>”中的“<”去匹配位置 6 左邊的第 3 個(gè)字符“<”,也匹配成功。那么最后“<B>”成功匹配到位置 6 左邊的字符串“<B>”,因?yàn)槭欠穸ōh(huán)視,所以整個(gè)逆序否定環(huán)視表達(dá)式匹配失敗(即位置 6 不符合要求),所以整個(gè)正則表達(dá)式的迭代匹配失敗,正則引擎的指針繼續(xù)向后移。
重復(fù)上述過程,直到正則引擎指針移到字符串結(jié)尾處,正則迭代匹配結(jié)束。
2. 逆序表達(dá)式的長度不固定,如何匹配
略
總結(jié)
以上是生活随笔為你收集整理的正则表达式的环视深度剖析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 正则表达式实例解读
- 下一篇: 正则表达式之 NFA 引擎匹配原理详解