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

Java 正則 Pattern 與 Matcher 深度解析:編譯、匹配模式、分組、替換與效能優化

     編輯:Java 相關知識

java.util.regex 包中的 Pattern (編譯後的正則) 與 Matcher (匹配狀態機) 是 Java 正則的核心雙子星。本文從捕獲組編號、三大匹配方法、分組提取、find() 迭代、替換操作、效能優化六大維度深度解析,附完整可執行代碼片段。

一、捕獲組編號規則

  • 從左到右數左括號,組 0 代表整個表達式。
  • 非捕獲組 (?:...) 不計編號、不捕獲文本。
  • 範例 ((A)(B(C))):組1=整體、組2=A、組3=B(C)、組4=C。

二、Pattern 核心方法

方法說明典型用途
compile(String regex)編譯正則,返回 Pattern靜態常量化複用
matcher(CharSequence)創建 Matcher後續所有匹配操作
matches(String, CharSequence)靜態快速匹配整串一次性驗證
split(CharSequence)分割字串等同 String.split()
pattern()返回原始正則字串除錯/日誌

三、Matcher 三大匹配模式對比

Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("22bb23");

m.matches();    // false - 必須匹配**整個**字串
m.lookingAt();  // true  - 只匹配**開頭** (22)
m.find();       // true  - 掃描**任意位置** (22)

四、分組提取與位置資訊

成功匹配後 (matches/lookingAt/find 返回 true) 可用:

方法說明
group() / group(int)捕獲文本 (組0/組N)
start() / start(int)起始索引 (inclusive)
end() / end(int)結束索引 (exclusive)
groupCount()捕獲組數量 (不含組0)
Pattern p = Pattern.compile("([a-z]+)(\\d+)");
Matcher m = p.matcher("aaa2223bb");
m.find(); // 匹配 aaa2223
m.group();      // "aaa2223"
m.group(1);     // "aaa"
m.group(2);     // "2223"
m.start(1);     // 0
m.end(1);       // 3
m.start(2);     // 3
m.end(2);       // 7

五、find() 迭代提取所有匹配

Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("QQ:456456 電話:0532214 Email:aaa123@bbb.com");
while (m.find()) {
  System.out.printf("值=%s 區間=[%d,%d)%n", m.group(), m.start(), m.end());
}
// 輸出:
// 值=456456 區間=[4,10)
// 值=0532214 區間=[12,19)
// 值=123 區間=[28,31)

六、替換操作

// 1. 全部替換為固定字串
String s1 = p.matcher("a1b2c3").replaceAll("#"); // "a#b#c#"

// 2. 替換為分組引用 ($1 $2)
String s2 = Pattern.compile("(\\d)(\\d)").matcher("12 34").replaceAll("$2$1"); // "21 43"

// 3. Java 9+ 函數式替換 (最強)
String s3 = Pattern.compile("\\d+")
    .matcher("價格100元 數量200個")
    .replaceAll(mr -> "[" + (Integer.parseInt(mr.group()) * 2) + "]");
// 結果: "價格[200]元 數量[400]個"

七、效能優化鐵律

  1. Pattern 編譯昂貴,務必複用:private static final Pattern EMAIL = Pattern.compile(...);
  2. 預編譯常用正則:Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL)。
  3. 避免災難性回溯:(a+)+、(.*)* 等嵌套量詞在長字串會指數級回溯,改用佔有優先量詞 (a++)+ 或原子組 (?>...)。
  4. 大量替換用 StringBuilder:Matcher.appendReplacement/appendTail 手動構建,避免 replaceAll 內部創建大量字串。
  5. Matcher 不可跨執行緒共用:有狀態,每執行緒自行 pattern.matcher(input)。

總結

掌握 Pattern 編譯複用、matches/lookingAt/find 三模式語義差異、分組提取與位置、find() 迭代、函數式替換 五大核心技能,即能駕馭 95% 正則場景。記住「編譯一次、匹配多次、慎用回溯、函數式替換」八字訣,寫出高效健壯的正則代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved