溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

VB.NET正則表達(dá)式的示例分析

發(fā)布時(shí)間:2021-12-02 10:44:42 來源:億速云 閱讀:226 作者:小新 欄目:編程語(yǔ)言

小編給大家分享一下VB.NET正則表達(dá)式的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

1.選擇符

VB.NET正則表達(dá)式中“ ¦”表示選擇。你可以用選擇符匹配多個(gè)可能的正則表達(dá)式中的一個(gè)。如果你想搜索文字“cat”或“dog”,你可以用﹤﹤cat ¦dog> > 。如果你想有更多的選擇,你只要擴(kuò)展列表﹤﹤cat ¦dog ¦mouse ¦fish> > 。選擇符在正則表達(dá)式中具有***的優(yōu)先級(jí),也就是說,它告訴引擎要么匹配選擇符左邊的所有表達(dá)式,要么匹配右邊的所有表達(dá)式。你也可以用圓括號(hào)來限制選擇符的作用范圍。如﹤﹤\b(cat ¦dog)\b> > ,這樣告訴正則引擎把(cat ¦dog)當(dāng)成一個(gè)正則表達(dá)式單位來處理。

注意正則引擎的“急于表功”性正則引擎是急切的,當(dāng)它找到一個(gè)有效的匹配時(shí),它會(huì)停止搜索。因此在一定條件下,選擇符兩邊的表達(dá)式的順序?qū)Y(jié)果會(huì)有影響。假設(shè)你想用正則表達(dá)式搜索一個(gè)編程語(yǔ)言的函數(shù)列表:Get,GetValue,Set或SetValue。一個(gè)明顯的解決方案是﹤﹤Get ¦GetValue ¦Set ¦SetValue> > 。讓我們看看當(dāng)搜索SetValue時(shí)的結(jié)果。因?yàn)椹偐侴et> > 和﹤﹤GetValue> > 都失敗了,而﹤﹤Set> > 匹配成功。因?yàn)檎齽t導(dǎo)向的引擎都是“急切”的,所以它會(huì)返回***個(gè)成功的匹配,就是“Set”,而不去繼續(xù)搜索是否有其他更好的匹配。和我們期望的相反,正則表達(dá)式并沒有匹配整個(gè)字符串。有幾種可能的解決辦法。

一是考慮到正則引擎的“急切”性,改變選項(xiàng)的順序,例如我們使用﹤﹤GetValue ¦Get ¦SetValue ¦Set> > ,這樣我們就可以優(yōu)先搜索最長(zhǎng)的匹配。我們也可以把四個(gè)選項(xiàng)結(jié)合起來成兩個(gè)選項(xiàng):﹤﹤Get(Value)? ¦Set(Value)?> > 。因?yàn)閱柼?hào)重復(fù)符是貪婪的,所以SetValue總會(huì)在Set之前被匹配。一個(gè)更好的方案是使用單詞邊界:﹤﹤\b(Get ¦GetValue ¦Set ¦SetValue)\b> > 或﹤﹤\b(Get(Value)? ¦Set(Value)?\b> > 。更進(jìn)一步,既然所有的選擇都有相同的結(jié)尾,我們可以把正則表達(dá)式優(yōu)化為﹤﹤\b(Get ¦Set)(Value)?\b> > 。

2.組與向后引用

把正則表達(dá)式的一部分放在圓括號(hào)內(nèi),你可以將它們形成組。然后你可以對(duì)整個(gè)組使用一些正則操作,例如重復(fù)操作符。要注意的是,只有圓括號(hào)“()”才能用于形成組?!癧]”用于定義字符集?!皗}”用于定義重復(fù)操作。當(dāng)用“()”定義了一個(gè)正則表達(dá)式組后,正則引擎則會(huì)把被匹配的組按照順序編號(hào),存入緩存。當(dāng)對(duì)被匹配的組進(jìn)行向后引用的時(shí)候,可以用“\數(shù)字”的方式進(jìn)行引用。﹤﹤\1> > 引用***個(gè)匹配的后向引用組,﹤﹤\2> > 引用第二個(gè)組,以此類推,﹤﹤\n> > 引用第n個(gè)組。而﹤﹤\0> > 則引用整個(gè)被匹配的正則表達(dá)式本身。我們看一個(gè)例子。假設(shè)你想匹配一個(gè)HTML標(biāo)簽的開始標(biāo)簽和結(jié)束標(biāo)簽,以及標(biāo)簽中間的文本。比如 Thisisatest ,我們要匹配 和 以及中間的文字。我們可以用如下正則表達(dá)式:“ <([A-Z][A-Z0-9]*)[^> ]*> .*? ”首先,“ <”將會(huì)匹配“ ”的***個(gè)字符“ <”。然后[A-Z]匹配B,[A-Z0-9]*將會(huì)匹配0到多次字母數(shù)字,后面緊接著0到多個(gè)非“> ”的字符。***正則表達(dá)式的“> ”將會(huì)匹配“ ”的“> ”。

接下來正則引擎將對(duì)結(jié)束標(biāo)簽之前的字符進(jìn)行惰性匹配,直到遇到一個(gè)“ ”你可以對(duì)相同的后向引用組進(jìn)行多次引用,﹤﹤([a-c])x\1x\1> > 將匹配“axaxa”、“bxbxb”以及“cxcxc”。如果用數(shù)字形式引用的組沒有有效的匹配,則引用到的內(nèi)容簡(jiǎn)單的為空。一個(gè)后向引用不能用于它自身。﹤﹤([abc]\1)> > 是錯(cuò)誤的。因此你不能將﹤﹤\0> > 用于一個(gè)正則表達(dá)式匹配本身,它只能用于替換操作中。后向引用不能用于字符集內(nèi)部。﹤﹤(a)[\1b]> > 中的﹤﹤\1> > 并不表示后向引用。在字符集內(nèi)部,﹤﹤\1> > 可以被解釋為八進(jìn)制形式的轉(zhuǎn)碼。向后引用會(huì)降低引擎的速度,因?yàn)樗枰鎯?chǔ)匹配的組。如果你不需要向后引用,你可以告訴引擎對(duì)某個(gè)組不存儲(chǔ)。例如:﹤﹤Get(?:Value)> > 。其中“(”后面緊跟的“?:”會(huì)告訴引擎對(duì)于組(Value),不存儲(chǔ)匹配的值以供后向引用。

重復(fù)操作與后向引用當(dāng)對(duì)組使用重復(fù)操作符時(shí),緩存里后向引用內(nèi)容會(huì)被不斷刷新,只保留***匹配的內(nèi)容。例如:﹤﹤([abc]+)=\1> > 將匹配“cab=cab”,但是﹤﹤([abc])+=\1> > 卻不會(huì)。因?yàn)?[abc])***次匹配“c”時(shí),“\1”代表“c”;然后([abc])會(huì)繼續(xù)匹配“a”和“b”。***“\1”代表“b”,所以它會(huì)匹配“cab=b”。應(yīng)用:檢查重復(fù)單詞--當(dāng)編輯文字時(shí),很容易就會(huì)輸入重復(fù)單詞,例如“thethe”。使用﹤﹤\b(\w+)\s+\1\b> > 可以檢測(cè)到這些重復(fù)單詞。要?jiǎng)h除第二個(gè)單詞,只要簡(jiǎn)單的利用替換功能替換掉“\1”就可以了。

組的命名和引用在PHP,Python中,可以用﹤﹤(?Pgroup)> > 來對(duì)組進(jìn)行命名。在本例中,詞法?P就是對(duì)組(group)進(jìn)行了命名。其中name是你對(duì)組的起的名字。你可以用(?P=name)進(jìn)行引用。.NET的命名組.NETframework也支持命名組。不幸的是,微軟的程序員們決定發(fā)明他們自己的語(yǔ)法,而不是沿用Perl、Python的規(guī)則。目前為止,還沒有任何其他的正則表達(dá)式實(shí)現(xiàn)支持微軟發(fā)明的語(yǔ)法。

下面是.NET中的例子:(?group)(?’second’group)正如你所看到的,.NET提供兩種詞法來創(chuàng)建命名組:一是用尖括號(hào)“ <> ”,或者用單引號(hào)“’’”。尖括號(hào)在字符串中使用更方便,單引號(hào)在ASP代碼中更有用,因?yàn)锳SP代碼中“ <> ”被用作HTML標(biāo)簽。要引用一個(gè)命名組,使用\k或\k’name’.當(dāng)進(jìn)行搜索替換時(shí),你可以用“${name}”來引用一個(gè)命名組。

3.VB.NET正則表達(dá)式的匹配模式

本教程所討論的正則表達(dá)式引擎都支持三種匹配模式:﹤﹤/i> > 使正則表達(dá)式對(duì)大小寫不敏感,﹤﹤/s> > 開啟“單行模式”,即點(diǎn)號(hào)“.”匹配新行符﹤﹤/m> > 開啟“多行模式”,即“^”和“$”匹配新行符的前面和后面的位置。

在正則表達(dá)式內(nèi)部打開或關(guān)閉模式如果你在正則表達(dá)式內(nèi)部插入修飾符(?ism),則該修飾符只對(duì)其右邊的正則表達(dá)式起作用。(?-i)是關(guān)閉大小寫不敏感。你可以很快的進(jìn)行測(cè)試。﹤﹤(?i)te(?-i)st> > 應(yīng)該匹配TEst,但是不能匹配teST或TEST.

4.原子組與防止回溯

在一些特殊情況下,因?yàn)榛厮輹?huì)使得引擎的效率極其低下。
讓我們看一個(gè)例子:要匹配這樣的字串,字串中的每個(gè)字段間用逗號(hào)做分隔符,第12個(gè)字段由P開頭。我們?nèi)菀紫氲竭@樣的正則表達(dá)式﹤﹤^(.*?,){11}P> > 。這個(gè)正則表達(dá)式在正常情況下工作的很好。但是在極端情況下,如果第12個(gè)字段不是由P開頭,則會(huì)發(fā)生災(zāi)難性的回溯。如要搜索的字串為“1,2,3,4,5,6,7,8,9,10,11,12,13”。首先,正則表達(dá)式一直成功匹配直到第12個(gè)字符。這時(shí),前面的正則表達(dá)式消耗的字串為“1,2,3,4,5,6,7,8,9,10,11,”,到了下一個(gè)字符,﹤﹤P> > 并不匹配“12”。所以引擎進(jìn)行回溯,這時(shí)正則表達(dá)式消耗的字串為“1,2,3,4,5,6,7,8,9,10,11”。繼續(xù)下一次匹配過程,下一個(gè)正則符號(hào)為點(diǎn)號(hào)﹤﹤.> > ,可以匹配下一個(gè)逗號(hào)“,”。然而﹤﹤,> > 并不匹配字符“12”中的“1”。匹配失敗,繼續(xù)回溯。大家可以想象,這樣的回溯組合是個(gè)非常大的數(shù)量。因此可能會(huì)造成引擎崩潰。

用于阻止這樣巨大的回溯有幾種方案:一種簡(jiǎn)單的方案是盡可能的使匹配精確。用取反字符集代替點(diǎn)號(hào)。例如我們用如下正則表達(dá)式﹤﹤^([^,\r\n]*,){11}P> > ,這樣可以使失敗回溯的次數(shù)下降到11次。另一種方案是使用原子組。原子組的目的是使正則引擎失敗的更快一點(diǎn)。因此可以有效的阻止海量回溯。原子組的語(yǔ)法是﹤﹤(?> 正則表達(dá)式)> > 。位于(?> )之間的所有正則表達(dá)式都會(huì)被認(rèn)為是一個(gè)單一的正則符號(hào)。一旦匹配失敗,引擎將會(huì)回溯到原子組前面的正則表達(dá)式部分。前面的例子用原子組可以表達(dá)成﹤﹤^(?> (.*?,){11})P> > 。一旦第十二個(gè)字段匹配失敗,引擎回溯到原子組前面的﹤﹤^> > 。

以上是“VB.NET正則表達(dá)式的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI