貪婪模式(Greedy):
數量表示符默認采用貪婪模式,除非另有表示。貪婪模式的表達式會一直匹配下去,直到無法匹配為止。如果你發現表達式匹配的結果與預期的不符,很有可能是因為——你以為表達式只會匹配前面幾個字符,而實際上它是貪婪模式,所以會一直匹配下去。
貪婪與非貪婪,加上?為非貪婪:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
var s = '1023000' .match(/(\d+)(0*)/); s [ "1023000" , "1023000" , "" ] var s = '1023000' .match(/^(\d+)(0*)$/); s [ "1023000" , "1023000" , "" ] var s = '1023000' .match(/^(\d+?)(0*)$/); s [ "1023000" , "1023" , "000" ] var s = '1023000' .match(/(\d+?)(0*)/); s [ "10" , "1" , "0" ] |
java 正則表達式默認用的是greedy貪婪匹配模式既是這種類型(.*)的最長匹配,如果需要最短匹配則改為(.*?)即是勉強匹配模式。
原理分析:
如果是貪婪匹配模式,正則表達式引擎會一直匹配到字符串最后,當匹配為false時,通過
回溯的方式,倒退找到倒數第一個匹配位置,返回匹配結果
如果是勉強匹配模式,正則表達式引擎會匹配到符合pattern的末尾位置那個字符,然后再往后走一步,發現匹配為false,又回溯到找到回退的最近一個匹配為true的位置,返回結果。
看代碼:
例一:
1
2
3
4
5
6
|
public void test51(){ String str = "aaa\"bbb\"ccc\"ddd\"eee" ; System.out.println(str); str = str.replaceAll( "\"(.*)\"" , "@" ); System.out.println(str); } |
輸出:
1
2
|
aaa"bbb"ccc"ddd"eee aaa@eee |
例二:
1
2
3
4
5
6
7
8
9
|
@Test public void test52(){ String str = "aaa\"bbb\"ccc\"ddd\"eee" ; System.out.println(str); str = str.replaceAll( "\"(.*?)\"" , "@" ); System.out.println(str); } |
輸出:
1
2
|
aaa"bbb"ccc"ddd"eee aaa@ccc@eee |