3分鐘讓你知道什么是VB.NET正則表達式引擎
本人很喜歡VB.NET正則表達式引擎,在工作中也很喜歡總結(jié)關(guān)于VB.NET正則表達式的經(jīng)驗教訓(xùn),下面就這個問題來詳細說說吧。
什么是正則表達式
基本說來,正則表達式是一種用來描述一定數(shù)量文本的模式。Regex代表RegularExpress。本文將用 <
向前查看與向后查看
Perl5引入了兩個強大的正則語法:“向前查看”和“向后查看”。他們也被稱作“零長度斷言”。他們和錨定一樣都是零長度的(所謂零長度即指該正則表達式不消耗被匹配的字符串)。不同之處在于“前后查看”會實際匹配字符,只是他們會拋棄匹配只返回匹配結(jié)果:匹配或不匹配。這就是為什么他們被稱作“斷言”。他們并不實際消耗字符串中的字符,而只是斷言一個匹配是否可能。幾乎本文討論的所有正則表達式的實現(xiàn)都支持“向前向后查看”。唯一的一個例外是Javascript只支持向前查看。
肯定和否定式的向前查看如我們前面提過的一個例子:要查找一個q,后面沒有緊跟一個u。也就是說,要么q后面沒有字符,要么后面的字符不是u。采用否定式向前查看后的一個解決方案為 < > 。否定式向前查看的語法是 < <(?!查看的內(nèi)容)> > ??隙ㄊ较蚯安榭春头穸ㄊ较蚯安榭春茴愃疲?< <(?=查看的內(nèi)容)> > 。如果在“查看的內(nèi)容”部分有組,也會產(chǎn)生一個向后引用。但是向前查看本身并不會產(chǎn)生向后引用,也不會被計入向后引用的編號中。這是因為向前查看本身是會被拋棄掉的,只保留匹配與否的判斷結(jié)果。如果你想保留匹配的結(jié)果作為向后引用,你可以用 < <(?=(regex))> > 來產(chǎn)生一個向后引用。
肯定和否定式的先后查看向后查看和向前查看有相同的效果,只是方向相反否定式向后查看的語法是: < <(? > 肯定式向后查看的語法是: < <(? <=查看內(nèi)容)> > 我們可以看到,和向前查看相比,多了一個表示方向的左尖括號。例: < <(? > 將會匹配一個沒有“a”作前導(dǎo)字符的“b”。值得注意的是:向前查看從當前字符串位置開始對“查看”正則表達式進行匹配;向后查看則從當前字符串位置開始先后回溯一個字符,然后再開始對“查看”正則表達式進行匹配。
深入VB.NET正則表達式引擎內(nèi)部讓我們看一個簡單例子。把正則表達式 < > 應(yīng)用到字符串“Iraq”。正則表達式的第一個符號是 <
> 。正如我們知道的,引擎在匹配 <
> 以前會掃過整個字符串。當?shù)谒膫€字符“q”被匹配后,“q”后面是空字符(void)。而下一個正則符號是向前查看。引擎注意到已經(jīng)進入了一個向前查看正則表達式部分。下一個正則符號是 < > ,和空字符不匹配,從而導(dǎo)致向前查看里的正則表達式匹配失敗。因為是一個否定式的向前查看,意味著整個向前查看結(jié)果是成功的。于是匹配結(jié)果“q”被返回了。我們在把相同的正則表達式應(yīng)用到“quit”。 <
> 匹配了“q”。下一個正則符號是向前查看部分的 < > ,它匹配了字符串中的第二個字符“i”。引擎繼續(xù)走到下個字符“i”。然而引擎這時注意到向前查看部分已經(jīng)處理完了,并且向前查看已經(jīng)成功。于是引擎拋棄被匹配的字符串部分,這將導(dǎo)致引擎回退到字符“u”。因為向前查看是否定式的,意味著查看部分的成功匹配導(dǎo)致了整個向前查看的失敗,因此引擎不得不進行回溯。最后因為再沒有其他的“q”和 <
> 匹配,所以整個匹配失敗了。為了確保你能清楚地理解向前查看的實現(xiàn),讓我們把 <
> 應(yīng)用到“quit”。 <
> 首先匹配“q”。然后向前查看成功匹配“u”,匹配的部分被拋棄,只返回可以匹配的判斷結(jié)果。引擎從字符“i”回退到“u”。由于向前查看成功了,引擎繼續(xù)處理下一個正則符號 < > 。結(jié)果發(fā)現(xiàn) < > 和“u”不匹配。因此匹配失敗了。由于后面沒有其他的“q”,整個正則表達式的匹配失敗了。
更進一步理解VB.NET正則表達式引擎內(nèi)部機制讓我們把 < <(? <=a)b> > 應(yīng)用到“thingamabob”。引擎開始處理向后查看部分的正則符號和字符串中的第一個字符。在這個例子中,向后查看告訴VB.NET正則表達式引擎回退一個字符,然后查看是否有一個“a”被匹配。因為在“t”前面沒有字符,所以引擎不能回退。因此向后查看失敗了。引擎繼續(xù)走到下一個字符“h”。再一次,引擎暫時回退一個字符并檢查是否有個“a”被匹配。結(jié)果發(fā)現(xiàn)了一個“t”。向后查看又失敗了。向后查看繼續(xù)失敗,直到正則表達式到達了字符串中的“m”,于是肯定式的向后查看被匹配了。因為它是零長度的,字符串的當前位置仍然是“m”。下一個正則符號是 < > ,和“m”匹配失敗。下一個字符是字符串中的第二個“a”。引擎向后暫時回退一個字符,并且發(fā)現(xiàn) < > 不匹配“m”。在下一個字符是字符串中的第一個“b”。引擎暫時性的向后退一個字符發(fā)現(xiàn)向后查看被滿足了,同時 < > 匹配了“b”。因此整個正則表達式被匹配了。作為結(jié)果,正則表達式返回字符串中的第一個“b”。
向前向后查看的應(yīng)用我們來看這樣一個例子:查找一個具有6位字符的,含有“cat”的單詞。首先,我們可以不用向前向后查看來解決問題,例如: <
【編輯推薦】