貪婪和非貪婪


  • 貪婪匹配:當正則表達式中包含能接受到重復的限定符時,通常的行為是匹配盡可能多的字符,這中匹配方式叫做貪婪匹配。特征是一次性讀入整個字符串經行匹配,每當不匹配就舍棄最右邊一個字符,繼續匹配,依次匹配和舍棄,直到匹配成功或者把整個字符串舍棄為止,因此它是一種最大化數據返回,能多不會少。

前面我們講過重復限定符,其實這些限定符就是貪婪量詞,比如表達式:\d{3,6}

用來匹配3到6位數字,在這種情況下,它是一種貪婪模式匹配,也就是假如字符串里有6個數字匹配,那它就會全部匹配到。

String test = "61762828 176 2991 871";
    String reg = "\\d{3,6}";
    Pattern pattern = Pattern.compile(reg);
    Matcher mc = pattern.matcher(test);
    while (mc.find()) {
        System.out.println("匹配結果:" + mc.group());
    }
    // 匹配結果:617628
    // 匹配結果:176
    // 匹配結果:2991
    // 匹配結果:871

由結果可見:本來字符串中的“61762828”這一段,其實只需要出現“617”就已經匹配成功了,但它並不滿足,而是匹配到了最大能匹配的字符,也就是6個。

那么有人會問,如果多個貪婪量詞湊在一起,那他們是如何支配自己的匹配權的呢?

是這樣的,多個貪婪在一起時,如果字符串能滿足他們各自最大程度的匹配時,就互不干擾,但如果不能滿足時,會根據深度優先的原則,也就是從左到右的每一個貪婪量詞,優先最大數量的滿足,剩余再分配下一個量詞匹配。

String test = "61762828 176 2991 87321";
    String reg = "(\\d{1,2})(\\d{3,4})";
    Pattern pattern = Pattern.compile(reg);
    Matcher mc = pattern.matcher(test);
    while (mc.find()) {
        System.out.println("匹配結果:" + mc.group());
    }
    // 匹配結果:617628
    // 匹配結果:2991
    // 匹配結果:87321

“617628” 是前面的\d{1,2}匹配出了61,后面的匹配出了7628

"2991" 是前面的\d{1,2}匹配出了29 ,后面的匹配出了91

"87321"是前面的\d{1,2}匹配出了87,后面的匹配出了321

  • 懶惰(非貪婪)

懶惰匹配:當正則表達式中包含能接受重復的限定符時,通常的行為是匹配盡可能少的字符,這種匹配方式叫做懶惰匹配。特性:從左到右,從字符串的最左邊開始匹配,每次試圖不讀入字符匹配,匹配成功,則完成匹配,否則讀入一個字符再匹配,依次循環(讀入字符,匹配)直到匹配成功或者把字符串的字符匹配完為止。

代碼 說明
*? 重復任意次,但盡可能少重復
+? 重復1次或更多次,但盡可能少重復
?? 重復0次或1次,但盡可能少重復
{n,m}? 重復n到m次,但盡可能少重復
{n,}? 重復n次以上,但盡可能少重復

 

 

 

 

 

 

String reg = "(\\d{1,2}?)(\\d{3,4})";
    String test = "61762828 176 2991 87321";
    System.out.println("文本:" + test);
    System.out.println("貪婪模式:" + reg);
    Pattern p1 = Pattern.compile(reg);
    Matcher m1 = p1.matcher(test);
    while (m1.find()) {
        System.out.println("匹配結果:" + m1.group(0));
    }
    // 文本:61762828 176 2991 87321
    // 貪婪模式:(\d{1,2}?)(\d{3,4})
    // 匹配結果:61762
    // 匹配結果:2991
    // 匹配結果:87321

 

 “61762” 是左邊的懶惰匹配出6,右邊的貪婪匹配出1762
"2991"  是左邊的懶惰匹配出2,右邊的貪婪匹配出991
"87321" 左邊的懶惰匹配出8,右邊的貪婪匹配出7321

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM