正則表達式,貪婪型,勉強型,佔有型

今天在做markdown轉換器項目時遇到了一個問題,讓我回顧了一下正則表達式中量詞的貪婪型,勉強型和佔有型這三種類型的匹配方式。這些匹配方式在匹配時需要根據項目需求合理地選擇搭配,否則程序結果可能完全出乎你的意料。

我的問題是,有如下字符串:“This is [google][1],this is [apple][2],and this is [ms][3].”
我需要依次將“[google][1]”,“[apple][2]”,“[ms][3]”給掃描出來。

最初我的做法是寫了如下的表達式:
Pattern pattern="\\[.+\\]\\[.+\\]"; 
我通過matcher.find()判斷是否找到,通過matcher.group()獲取掃描到的子串,可是當我運行程序後,卻只得到了[google][1],this is [apple][2],and this is [ms][3],由此引出了三種匹配類型這一問題。

java正則表達式默認匹配是貪婪型(最大匹配),也就是說,會儘可能去尋找最長的能夠匹配的子串,此時[go.......................ms]顯然是能夠匹配的最長子串。
而如果要滿足我的需求,則應該選擇使用勉強型匹配,也叫最小匹配。它的寫法是,在需要最小串長就匹配成功的地方,加上?。在此例中,我們希望'['在一遇到"]["出就匹配,而最後也要儘快匹配']',故,我們要這麼寫:
Pattern pattern="\\[.+?\\]\\[.+?\\]";
這兩個問號就是我們希望儘快匹配的位置,所以後來我選擇了這種方式成功輸出了結果。

那java中還有一種佔有型匹配是怎麼回事呢?它的寫法是,在你希望要儘可能多匹配的位置加上一個+,它和貪婪型的區別在於,貪婪型在嘗試匹配儘量多的字符時,一旦發現最終無法滿足要求,它是會回溯的,重新尋找,直至找到(詳細算法我暫時還沒看源碼,但不影響我們掌握它的思路),當然如果實在沒有也沒辦法。而佔有型則是,當遇到pattern中使用+來表示要佔有匹配時,它就儘可能的和源字符串進行匹配,直至無法繼續,然後在去匹配正則式中下面的部分,如果下面的部分無法匹配,此時是不會像最大匹配那樣回溯的。find(),match() 都會返回false。舉個直觀的例子吧:
Pattern pattern_tanlan="\\w+\\w";
Pattern pattern_zhanyou="\\w++\\w";
以上分別是貪婪型和佔有型,面對這樣的源字符串:“This is [google][1],this is [apple][2],and this is [ms][3].”貪婪型可以成功find出:“This”,"is","google","this","is","apple","and","this","is","ms"這些子串,而佔有型則一個也沒有。因爲匹配\\w時,它們都是儘量往後匹配,以This爲例,都匹配到了字母s,可是空格就無法匹配了,然後pattern_tanlan後頭的\\w無法匹配,它就回溯,最終讓後一個\\w匹配s,而\\w+匹配Thi,但是佔有型則不,它不回溯,也就一個也匹配不成了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章