?*或+正則表達式使用詳解
?*或+正則表達式使用詳解是向你介紹我們使用?*或+實現(xiàn)“重復(fù)”的操作,那么具體的有哪些方面呢?我們下面通過實例的講解形式向你逐一介紹,希望對你有所幫助。
?*或+正則表達式使用詳解之相關(guān)概念:
?:告訴引擎匹配前導(dǎo)字符0次或一次。事實上是表示前導(dǎo)字符是可選的。
+:告訴引擎匹配前導(dǎo)字符1次或多次
*:告訴引擎匹配前導(dǎo)字符0次或多次
<[A-Za-z][A-Za-z0-9]*>匹配沒有屬性的HTML標(biāo)簽,“<”以及“>”是文字符號。第一個字符集匹配一個字母,第二個字符集匹配一個字母或數(shù)字。
我們似乎也可以用<[A-Za-z0-9]+>。但是它會匹配<1>。但是這個正則表達式在你知道你要搜索的字符串不包含類似的無效標(biāo)簽時還是足夠有效的。
◆?*或+正則表達式使用詳解之限制性重復(fù)
許多現(xiàn)代的正則表達式實現(xiàn),都允許你定義對一個字符重復(fù)多少次。詞法是:{min,max}。min和max都是非負整數(shù)。如果逗號有而max被忽略了,則max沒有限制。如果逗號和max都被忽略了,則重復(fù)min次。
因此{0,}和*一樣,{1,}和+ 的作用一樣。
你可以用<<\b[1-9][0-9]{3}\b>>匹配1000~9999之間的數(shù)字(“\b”表示單詞邊界)。<<\b[1-9][0-9]{2,4}\b>>匹配一個在100~99999之間的數(shù)字。
◆?*或+正則表達式使用詳解之注意貪婪性
假設(shè)你想用一個正則表達式匹配一個HTML標(biāo)簽。你知道輸入將會是一個有效的HTML文件,因此正則表達式不需要排除那些無效的標(biāo)簽。所以如果是在兩個尖括號之間的內(nèi)容,就應(yīng)該是一個HTML標(biāo)簽。
許多正則表達式的新手會首先想到用正則表達式<< <.+> >>,他們會很驚訝的發(fā)現(xiàn),對于測試字符串,“This is a <EM>first</EM> test”,你可能期望會返回<EM>,然后繼續(xù)進行匹配的時候,返回</EM>。
但事實是不會。正則表達式將會匹配“<EM>first</EM>”。很顯然這不是我們想要的結(jié)果。原因在于“+”是貪婪的。也就是說,“+”會導(dǎo)致正則表達式引擎試圖盡可能的重復(fù)前導(dǎo)字符。只有當(dāng)這種重復(fù)會引起整個正則表達式匹配失敗的情況下,引擎會進行回溯。也就是說,它會放棄最后一次的“重復(fù)”,然后處理正則表達式余下的部分。和“+”類似,“?*”的重復(fù)也是貪婪的。
◆?*或+正則表達式使用詳解之深入正則表達式引擎內(nèi)部
讓我們來看看正則引擎如何匹配前面的例子。第一個記號是“<”,這是一個文字符號。第二個符號是“.”,匹配了字符“E”,然后“+”一直可以匹配其余的字符,直到一行的結(jié)束。然后到了換行符,匹配失敗(“.”不匹配換行符)。于是引擎開始對下一個正則表達式符號進行匹配。也即試圖匹配“>”。到目前為止,“<.+”已經(jīng)匹配了“<EM>first</EM> test”。引擎會試圖將“>”與換行符進行匹配,結(jié)果失敗了。于是引擎進行回溯。結(jié)果是現(xiàn)在“<.+”匹配“<EM>first</EM> tes”。于是引擎將“>”與“t”進行匹配。顯然還是會失敗。這個過程繼續(xù),直到“<.+”匹配“<EM>first</EM”,“>”與“>”匹配。于是引擎找到了一個匹配“<EM>first</EM>”。記住,正則導(dǎo)向的引擎是“急切的”,所以它會急著報告它找到的第一個匹配。而不是繼續(xù)回溯,即使可能會有更好的匹配,例如“<EM>”。所以我們可以看到,由于“+”的貪婪性,使得正則表達式引擎返回了一個最左邊的最長的匹配。
◆?*或+正則表達式使用詳解之用懶惰性取代貪婪性
一個用于修正以上問題的可能方案是用“+”的惰性代替貪婪性。你可以在“+”后面緊跟一個問號“?”來達到這一點?!?”,“{}”和“?”表示的重復(fù)也可以用這個方案。因此在上面的例子中我們可以使用“<.+?>”。讓我們再來看看正則表達式引擎的處理過程。
再一次,正則表達式記號“<”會匹配字符串的第一個“<”。下一個正則記號是“.”。這次是一個懶惰的“+”來重復(fù)上一個字符。這告訴正則引擎,盡可能少的重復(fù)上一個字符。因此引擎匹配“.”和字符“E”,然后用“>”匹配“M”,結(jié)果失敗了。引擎會進行回溯,和上一個例子不同,因為是惰性重復(fù),所以引擎是擴展惰性重復(fù)而不是減少,于是“<.+”現(xiàn)在被擴展為“<EM”。引擎繼續(xù)匹配下一個記號“>”。這次得到了一個成功匹配。引擎于是報告“<EM>”是一個成功的匹配。整個過程大致如此。
◆?*或+正則表達式使用詳解之惰性擴展的一個替代方案
我們還有一個更好的替代方案??梢杂靡粋€貪婪重復(fù)與一個取反字符集:“<[^>]+>”。之所以說這是一個更好的方案在于使用惰性重復(fù)時,引擎會在找到一個成功匹配前對每一個字符進行回溯。而使用取反字符集則不需要進行回溯。
最后要記住的是,本教程僅僅談到的是正則導(dǎo)向的引擎。文本導(dǎo)向的引擎是不回溯的。但是同時他們也不支持惰性重復(fù)操作。
?*或+正則表達式使用詳解的基本內(nèi)容就向你介紹到這里,希望對你學(xué)習(xí)?*或+正則表達式使用詳解有所幫助。
【編輯推薦】