首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 正則表達式量詞深度解析:貪婪、勉強、獨占模式的區別與實戰

     編輯:Java 綜合教學

Java 正則表達式量詞深度解析:Greedy vs Reluctant vs Possessive

正則量詞決定「匹配多少次」,Java 提供三種模式,行為差異巨大,掌握它們是寫出高性能、正確正則的關鍵。

量詞對照表

匹配次數貪婪勉強獨占
0 或 1X?X??X?+
0 或多X*X*?X*+
1 或多X+X+?X++
恰好 nX{n}X{n}?X{n}+
至少 nX{n,}X{n,}?X{n,}+
n 到 mX{n,m}X{n,m}?X{n,m}+

核心行為差異

  • 貪婪:盡可能多匹配,匹配失敗時回溯嘗試少匹配。
  • 勉強:盡可能少匹配,逐步擴大嘗試,不回溯(因為本來就從少開始)。
  • 獨占:像貪婪一樣盡可能多匹配,但絕不回溯,匹配失敗直接整體失敗。

實戰驗證代碼

public class QuantifierDemo {
    public static void main(String[] args) {
        String text = "ababa";
        test("\\w+",   text, "貪婪 \\w+");
        test("\\w+?",  text, "勉強 \\w+?");
        test("\\w++",  text, "獨占 \\w++");

        System.out.println("--- 加上尾部 b ---");
        test("\\w+b",   text, "貪婪 \\w+b");
        test("\\w+?b",  text, "勉強 \\w+?b");
        test("\\w++b",  text, "獨占 \\w++b");
    }
    static void test(String regex, String text, String label) {
        Matcher m = Pattern.compile(regex).matcher(text);
        System.out.print(label + " => ");
        while (m.find()) {
            System.out.printf("[%d-%d:%s] ", m.start(), m.end(), m.group());
        }
        System.out.println();
    }
}

輸出與解讀

貪婪 \w+      => [0-5:ababa]
勉強 \w+?     => [0-1:a] [1-2:b] [2-3:a] [3-4:b] [4-5:a]
獨占 \w++     => [0-5:ababa]

--- 加上尾部 b ---
貪婪 \w+b     => [0-4:abab]   // \w+ 先吞全串,回溯 1 字符匹配 b
勉強 \w+?b    => [0-2:ab] [2-4:ab]  // 每次最少匹配 1 個字符再試 b
獨占 \w++b    => (無匹配)    // \w++ 吞全串,無回溯,b 匹配失敗整體失敗

性能與選型指南

  1. 預設用貪婪:最直觀,現代引擎優化極好,除非發生災難性回溯。
  2. 已知邊界用獨占:如 \d++ 匹配純數字串,明確後面不可能是數字,獨占避免回溯開銷,防止 ReDoS。
  3. 需最小匹配用勉強:如解析 HTML 屬性 ".*?",但慎用於大文本,可能導致大量嘗試,優於貪婪回溯但仍有性能隱患。
  4. 終極優化:用具體字符類代替 .、\w,如 [^"]* 替代 ".*?",從根源消除回溯。
更多內容:Java 正則規則表 | Pattern 類詳解 | Matcher 類詳解
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved