這篇文章給大家分享的是有關(guān)正則基礎(chǔ)之環(huán)視的示例分析的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
主要從事網(wǎng)頁(yè)設(shè)計(jì)、PC網(wǎng)站建設(shè)(電腦版網(wǎng)站建設(shè))、wap網(wǎng)站建設(shè)(手機(jī)版網(wǎng)站建設(shè))、成都響應(yīng)式網(wǎng)站建設(shè)公司、程序開(kāi)發(fā)、微網(wǎng)站、小程序定制開(kāi)發(fā)等,憑借多年來(lái)在互聯(lián)網(wǎng)的打拼,我們?cè)诨ヂ?lián)網(wǎng)網(wǎng)站建設(shè)行業(yè)積累了豐富的網(wǎng)站設(shè)計(jì)、做網(wǎng)站、網(wǎng)絡(luò)營(yíng)銷(xiāo)經(jīng)驗(yàn),集策劃、開(kāi)發(fā)、設(shè)計(jì)、營(yíng)銷(xiāo)、管理等多方位專(zhuān)業(yè)化運(yùn)作于一體,具備承接不同規(guī)模與類(lèi)型的建設(shè)項(xiàng)目的能力。環(huán)視(Lookaround)
環(huán)視只進(jìn)行子表達(dá)式的匹配,不占有字符,匹配到的內(nèi)容不保存到最終的匹配結(jié)果,是零寬度的。環(huán)視匹配的最終結(jié)果就是一個(gè)位置。
環(huán)視的作用相當(dāng)于對(duì)所在位置加了一個(gè)附加條件,只有滿(mǎn)足這個(gè)條件,環(huán)視子表達(dá)式才能匹配成功。
環(huán)視按照方向劃分有順序和逆序兩種,按照是否匹配有肯定和否定兩種,組合起來(lái)就有四種環(huán)視。順序環(huán)視相當(dāng)于在當(dāng)前位置右側(cè)附加一個(gè)條件,而逆序環(huán)視相當(dāng)于在當(dāng)前位置左側(cè)附加一個(gè)條件。
表達(dá)式
說(shuō)明
(?<=Expression)
逆序肯定環(huán)視,表示所在位置左側(cè)能夠匹配Expression
(?
逆序否定環(huán)視,表示所在位置左側(cè)不能匹配Expression
(?=Expression)
順序肯定環(huán)視,表示所在位置右側(cè)能夠匹配Expression
(?!Expression)
順序否定環(huán)視,表示所在位置右側(cè)不能匹配Expression
對(duì)于環(huán)視的叫法,有的文檔里叫預(yù)搜索,有的叫什么什么斷言的,這里使用了更多人容易接受的《精通正則表達(dá)式》中“環(huán)視”的叫法,其實(shí)叫什么無(wú)所謂,只要知道是什么作用就是了,就這么幾個(gè)語(yǔ)法規(guī)則, 還是很容易記的
環(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)視也就沒(méi)什么秘密可言了。
對(duì)于順序肯定環(huán)視(?=Expression)來(lái)說(shuō),當(dāng)子表達(dá)式Expression匹配成功時(shí),(?=Expression)匹配成功,并報(bào)告(?=Expression)匹配當(dāng)前位置成功。
對(duì)于順序否定環(huán)視(?!Expression)來(lái)說(shuō),當(dāng)子表達(dá)式Expression匹配成功時(shí),(?!Expression)匹配失?。划?dāng)子表達(dá)式Expression匹配失敗時(shí),(?!Expression)匹配成功,并報(bào)告(?!Expression)匹配當(dāng)前位置成功;
順序肯定環(huán)視的例子已在NFA引擎匹配原理中講解過(guò)了,這里再講解一下順序否定環(huán)視。
源字符串:aa one two
正則表達(dá)式:<(?!/?pb)[^>]+>
這個(gè)正則的意義就是匹配除
或
之外的其余標(biāo)簽。匹配過(guò)程:
首先由字符“<”取得控制權(quán),從位置0開(kāi)始匹配,由于“<”匹配“a”失敗,在位置0處整個(gè)表達(dá)式匹配失敗,第一次迭代匹配失敗,正則引擎向前傳動(dòng),由位置1處開(kāi)始嘗試第二次迭代匹配。
重復(fù)以上過(guò)程,直到位置2,“<”匹配“<”成功,控制權(quán)交給“(?!/?pb)”;“(?!/?pb)”子表達(dá)式取得控制權(quán)后,進(jìn)行內(nèi)部子表達(dá)式的匹配。首先由“/?”取得控制權(quán),嘗試匹配“p”失敗,進(jìn)行回溯,不匹配,控制權(quán)交給“p”;由“p”來(lái)嘗試匹配“p”,匹配成功,控制權(quán)交給“b”;由“b”來(lái)嘗試匹配位置4,匹配成功。此時(shí)子表達(dá)式匹配完成,“/?pb”匹配成功,那么環(huán)視表達(dá)式“(?!/?pb)”就匹配失敗。在位置2處整個(gè)表達(dá)式匹配失敗,新一輪迭代匹配失敗,正則引擎向前傳動(dòng),由位置3處開(kāi)始嘗試下一輪迭代匹配。
在位置8處也會(huì)遇到一輪“/?pb”匹配“/p”成功,而導(dǎo)致環(huán)視表達(dá)式“(?!/?pb)”匹配失敗,從而導(dǎo)致整個(gè)表達(dá)式匹配失敗的過(guò)程。
重復(fù)以上過(guò)程,直到位置14,“<”匹配“<”成功,控制權(quán)交給“(?!/?pb)”;“/?”嘗試匹配“d”失敗,進(jìn)行回溯,不匹配,控制權(quán)交給“p”;由“p”來(lái)嘗試匹配“d”,匹配失敗,已經(jīng)沒(méi)有備選狀態(tài)可供回溯,匹配失敗。此時(shí)子表達(dá)式匹配完成,“/?pb”匹配失敗,那么環(huán)視表達(dá)式“(?!/?pb)”就匹配成功。匹配的結(jié)果是位置15,然后控制權(quán)交給“[^>]+”;由“[^>]+”從位置15進(jìn)行嘗試匹配,可以成功匹配到“p”,控制權(quán)交給“>”;由“>”來(lái)匹配“>”。
此時(shí)正則表達(dá)式匹配完成,報(bào)告匹配成功。匹配結(jié)果為“”,開(kāi)始位置為14,結(jié)束位置為19。其中“<”匹配“<”,“(?!/?pb)”匹配位置15,“[^>]+”匹配字符串“p”,“>”匹配“>”。
對(duì)于逆序肯定環(huán)視(?<=Expression)來(lái)說(shuō),當(dāng)子表達(dá)式Expression匹配成功時(shí),(?<=Expression)匹配成功,并報(bào)告(?<=Expression)匹配當(dāng)前位置成功。
對(duì)于逆序否定環(huán)視(?來(lái)說(shuō),當(dāng)子表達(dá)式Expression匹配成功時(shí),(?匹配失??;當(dāng)子表達(dá)式Expression匹配失敗時(shí),(?匹配成功,并報(bào)告(?匹配當(dāng)前位置成功;
順序環(huán)視相當(dāng)于在當(dāng)前位置右側(cè)附加一個(gè)條件,所以它的匹配嘗試是從當(dāng)前位置開(kāi)始的,然后向右嘗試匹配,直到某一位置使得匹配成功或失敗為止。而逆序環(huán)視的特殊處在于,它相當(dāng)于在當(dāng)前位置左側(cè)附加一個(gè)條件,所以它不是在當(dāng)前位置開(kāi)始嘗試匹配的,而是從當(dāng)前位置左側(cè)某一位置開(kāi)始,匹配到當(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ì)是簡(jiǎn)單的,而逆序環(huán)視相對(duì)是復(fù)雜的。這也就是為什么大多數(shù)語(yǔ)言和工具都提供了對(duì)順序環(huán)視的支持,而只有少數(shù)語(yǔ)言提供了對(duì)逆序環(huán)視支持的原因。
JavaScript中只支持順序環(huán)視,不支持逆序環(huán)視。
Java中雖然順序環(huán)視和逆序環(huán)視都支持,但是逆序環(huán)視只支持長(zhǎng)度確定的表達(dá)式,逆序環(huán)視中量詞只支持“?”,不支持其它長(zhǎng)度不定的量詞。長(zhǎng)度確定時(shí),引擎可以向左查找固定長(zhǎng)度的位置作為起點(diǎn)開(kāi)始嘗試匹配,而如果長(zhǎng)度不確定時(shí),就要從當(dāng)前位置向左逐個(gè)位置開(kāi)始嘗試匹配,不成功則回溯,再向左側(cè)位置進(jìn)行嘗試匹配,然后重復(fù)以上過(guò)程,直到匹配成功,或是嘗試到位置0處以后,報(bào)告匹配失敗,處理的復(fù)雜度是顯而易見(jiàn)的。
目前只有.NET中支持不確定長(zhǎng)度的逆序環(huán)視。
源字符串: a test
正則表達(dá)式:(?<= )[^<]+(?=
這個(gè)正則的意義就是匹配
和
標(biāo)簽之間的內(nèi)容,而不包括和
標(biāo)簽本身。匹配過(guò)程:
首先由“(?<= ) )
直到傳動(dòng)到位置5,“(?<= ) )
此時(shí)正則表達(dá)式匹配完成,報(bào)告匹配成功。匹配結(jié)果為“a test”,開(kāi)始位置為5,結(jié)束位置為11。其中“(?<= )
逆序否定環(huán)視的匹配過(guò)程與上述過(guò)程類(lèi)似,區(qū)別只是當(dāng)Expression匹配失敗時(shí),逆序否定表達(dá)式(?才匹配成功。
到此環(huán)視的匹配原理已基本講解完,環(huán)視也就沒(méi)有什么秘密可言了,所需要的,也只是多加練習(xí)而已。
今天寫(xiě)累了,暫時(shí)就給出一個(gè)環(huán)視的綜合應(yīng)用實(shí)例吧,至于環(huán)視的應(yīng)用場(chǎng)景和技巧,后面再整理。
需求:數(shù)字格式化成用“,”的貨幣格式。
正則表達(dá)式:(?n)(?<=d)(?
測(cè)試代碼:
double[] data = new double[] { 0, 12, 123, 1234, 12345, 123456, 1234567, 123456789, 1234567890, 12.345, 123.456, 1234.56, 12345.6789, 123456.789, 1234567.89, 12345678.9 };
foreach (double d in data)
{
richTextBox2.Text += "源字符串:" + d.ToString().PadRight(15) + "格式化:" + Regex.Replace(d.ToString(), @"(?n)(?<=d)(?
}
輸出結(jié)果:
源字符串:0 格式化:0
源字符串:12 格式化:12
源字符串:123 格式化:123
源字符串:1234 格式化:1,234
源字符串:12345 格式化:12,345
源字符串:123456 格式化:123,456
源字符串:1234567 格式化:1,234,567
源字符串:123456789 格式化:123,456,789
源字符串:1234567890 格式化:1,234,567,890
源字符串:12.345 格式化:12.345
源字符串:123.456 格式化:123.456
源字符串:1234.56 格式化:1,234.56
源字符串:12345.6789 格式化:12,345.6789
源字符串:123456.789 格式化:123,456.789
源字符串:1234567.89 格式化:1,234,567.89
源字符串:12345678.9 格式化:12,345,678.9
實(shí)現(xiàn)分析:
首先根據(jù)需求可以確定是把一些特定的位置替換為“,”,接下來(lái)就是分析并找到這些位置的規(guī)律,并抽象出來(lái)以正則表達(dá)式來(lái)表示。
1、 這個(gè)位置的左側(cè)必須為數(shù)字
2、 這個(gè)位置右側(cè)到出現(xiàn)“.”或結(jié)尾為止,必須是數(shù)字,且數(shù)字的個(gè)數(shù)必須為3的倍數(shù)
3、 這個(gè)位置左側(cè)相隔任意個(gè)數(shù)字不能出現(xiàn)“.”
由以上三條,就可以完全確定這些位置,只要實(shí)現(xiàn)以上三條,組合一下正則表達(dá)式就可以了。
根據(jù)分析,最終匹配的結(jié)果是一個(gè)位置,所以所有子表達(dá)式都要求是零寬度。
1、 是對(duì)當(dāng)前所在位置左側(cè)附加的條件,所以要用到逆序環(huán)視,因?yàn)橐蟊仨毘霈F(xiàn),所以是肯定的,符合這一條件的子表達(dá)式即為“(?<=d)”
2、 是對(duì)當(dāng)前所在位置右側(cè)附加的條件,所以要用到順序環(huán)視,也是要求出現(xiàn),所以是肯定的,是數(shù)字,且個(gè)數(shù)為3的倍數(shù),即“(?=(d{3})+)”,到出現(xiàn)“.”或結(jié)尾為止,即“(?=(d{3})+(.|$))”
3、 是對(duì)當(dāng)前所在位置左側(cè)附加的條件,所以要用到逆序環(huán)視,因?yàn)橐蟛荒艹霈F(xiàn),所以是否定的,即“(?”
因?yàn)榱銓挾鹊淖颖磉_(dá)式是非互斥的,最后匹配的都是同一個(gè)位置,所以先后順序是不影響最后的匹配結(jié)果的,可以任意組合,只是習(xí)慣上把逆序環(huán)視寫(xiě)在左側(cè),順序環(huán)視寫(xiě)在右側(cè)。
說(shuō)明:這里只是為了說(shuō)明環(huán)視的使用而舉的一個(gè)例子,實(shí)際上這個(gè)需求直接用string.Format就可以做到
感謝各位的閱讀!關(guān)于“正則基礎(chǔ)之環(huán)視的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!