Java正則表達式匹配模式[貪婪型、勉強型、佔有型]

http://www.51itong.net/java-regex-greedy-reluctant-possessive-248.html

對於這三種匹配模式也有叫: 最大匹配Greedy”“最小匹配Reluctant”“完全匹配Possessive”。現在將我對這三種匹配模式的理解寫出來,並提供一些例子供大家參考。

1、Greediness(貪婪型): 最大匹配

X?、X*、X+、X{n,}都是最大匹配。例如你要用“<.+>”去匹配“a<tr>aava </tr>abb”,也許你所期待的結果是想匹配“<tr>”,但是實際結果卻會匹配到“<tr>aava </tr>”。這是爲什麼呢?下面我們跟蹤下最大匹配的匹配過程。

①“<”匹配字符串的“<”。②“.+”匹配字符串的“tr>aava </tr>ab”,在進行最大匹配時,它把兩個“>”都匹配了,它匹配了所有字符,直到文本的最後字符“b” ③這時,發現不能成功匹配“>”,開始按原路回退,用“a”與“>”匹配,直到“ab”前面的“>”匹配成功。

這就是最大匹配,我們匹配的時候應該看最後面能匹配到哪。

代碼示例:

1 String test = "a<tr>aava </tr>abb ";
2 String reg = "<.+>";
3 System.out.println(test.replaceAll(reg, "###"));

輸出:

a###abb

2、Reluctant(Laziness)(勉強型):最小匹配 

X?、X*、X+、X{n,}都是最大匹配。好,加個?就成了Laziness匹配。例如X??、X*?、X+?、X{n,}?都是最小匹配,其實X{n,m}?和X{n }?有些多餘。

最小匹配意味者,.+? 匹配一個字符後,馬上試一試>的匹配可能,失敗了,則.+? 再匹配一個字符,再馬上試一試>的匹配可能。JDK文檔中Greedy 和 Reluctant,它是以eat一口來隱喻的,所以翻譯成貪吃和(勉強的)厭食最貼切了。不過我喜歡最大匹配、最小匹配的說法。

代碼示例:

1 String test = "a<tr>aava </tr>abb ";
2 String reg = "<.+?>";
3 System.out.println(test.replaceAll(reg, "###"));

輸出:

a###aava ###abb

和上面的不同是匹配了兩處。

3、Possessive(佔有型):完全匹配 

與最大匹配不同,還有一種匹配形式:X?+、X*+、X++、X{n,}+等,成爲完全匹配。它和最大匹配一樣,一直匹配所有的字符,直到文本的最後,但它不由原路返回。也就是說,一口匹配,搞不定就算了,到也乾脆,偶喜歡。

代碼示例:

1 String test = "a<tr>aava </tr>abb ";
2         String test2 = "<tr>";
3         String reg = "<.++>";
4         String reg2 = "<tr>";
5         System.out.println(test.replaceAll(reg, "###"));
6         System.out.println(test2.replaceAll(reg2, "###"));

輸出:

a<tr>aava </tr>abb
###

可見。完全匹配是最嚴格的,必須整個字符串匹配才行。



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