5. 最小組團(tuán)(Atomic Groups)
最小組團(tuán)是無捕捉的特殊正則表達(dá)式分組。通常用來提高正則表達(dá)式的效能,也能用于消除特定匹配。一個最小組團(tuán)可以用(?>pattern) 來定義,其中pattern是匹配式。
/(?>his|this)/
當(dāng)正則引擎針對最小組團(tuán)進(jìn)行匹配時,它會跳過組團(tuán)內(nèi)標(biāo)記的回溯位置。以單詞“smashing”為例,當(dāng)用上面的正則表達(dá)式匹配時,正則引擎會先嘗試在“smashing”里尋找“his”。顯然,找不到任何匹配。此時,最小組團(tuán)就發(fā)揮作用了:正則引擎會放棄所有回溯位置。也就是說,它不會嘗試再從“smashing”里查找“this”。為什么要這樣設(shè)置?因?yàn)椤癶is”都沒有返回匹配結(jié)果,包含有“his”的“this”當(dāng)然就更匹配不了了!
上面的例子并沒有什么實(shí)用性,我們用/t?his?/ 也能達(dá)到效果。再看看下面的例子:
/\b(engineer|engrave| end )\b/
如果把“engineering”拿去匹配,正則引擎會先匹配到“engineer”,但接下來就遇到了字詞邊界,\b ,所以匹配不成功。然后,正則引擎又會嘗試在字串里尋找下一個匹配內(nèi)容:engrave。匹配到eng的時候,后面的又對不上了,匹配失敗。最后,嘗試“end”,結(jié)果同樣是失敗。仔細(xì)觀察,你會發(fā)現(xiàn),一旦engineer匹配失敗,并且都抵達(dá)了字詞邊界,“engrave”和“end”這兩個詞就已經(jīng)不可能匹配成功了。這兩個詞都比engineer短小,正則引擎不應(yīng)該再多做無謂的嘗試。
/\b(?>engineer|engrave| end )\b/
上面的替代寫法更能節(jié)省正則引擎的匹配時間,提高代碼的工作效率。
6. 遞歸(Recursion)
遞歸(Recursion)用于匹配嵌套結(jié)構(gòu),例如括弧嵌套, (this (that)),HTML標(biāo)簽嵌套<div> <div></div> </div> 。我們使用(?R) 來代表遞歸過程中的子模式。下面是一個匹配嵌套括弧的例子:
/\(((?>[^()]+)|(?R))*\)/
最外層使用了反義符的括號“\( ”匹配嵌套結(jié)構(gòu)的開端。然后是一個多選項(xiàng)操作符( * | * ) ,可能匹配除括號外的所有字符 “(?>[^()]+) ”,也可能是通過子模式“(?R) ”來再次匹配整個表達(dá)式。請注意,這個操作符會盡量多地匹配所有嵌套。
遞歸的另一個實(shí)例如下:
/<([\w]+).*?>((?>[^<>]+)|((?R)))*<\/\1>/
以上表達(dá)式綜合運(yùn)用了字符分組,貪婪操作符、回溯,以及最小化組團(tuán)來匹配嵌套標(biāo)簽。第一個括弧內(nèi)分組([w]+) 匹配出標(biāo)簽名,用于接下來的應(yīng)用。若找到這尖括號樣式的標(biāo)簽,則嘗試尋找標(biāo)簽內(nèi)容的剩余部分。下一個括弧括起來的子表達(dá)式和上一個實(shí)例非常相似:要么匹配不包括尖括號的所有字符 ?>[^<>]+ ,要么遞歸匹配整個表達(dá)式(?R) 。表達(dá)式最后的</1> 代表閉合標(biāo)簽。
出處:笨活兒
責(zé)任編輯:bluehearts
上一頁 正則表達(dá)式高級技巧及實(shí)例詳解 [3] 下一頁 正則表達(dá)式高級技巧及實(shí)例詳解 [5]
◎進(jìn)入論壇網(wǎng)絡(luò)編程版塊參加討論
|