java.util.regex 包中的 Pattern (編譯後的正則) 與 Matcher (匹配狀態機) 是 Java 正則的核心雙子星。本文從捕獲組編號、三大匹配方法、分組提取、find() 迭代、替換操作、效能優化六大維度深度解析,附完整可執行代碼片段。
(?:...) 不計編號、不捕獲文本。((A)(B(C))):組1=整體、組2=A、組3=B(C)、組4=C。| 方法 | 說明 | 典型用途 |
|---|---|---|
compile(String regex) | 編譯正則,返回 Pattern | 靜態常量化複用 |
matcher(CharSequence) | 創建 Matcher | 後續所有匹配操作 |
matches(String, CharSequence) | 靜態快速匹配整串 | 一次性驗證 |
split(CharSequence) | 分割字串 | 等同 String.split() |
pattern() | 返回原始正則字串 | 除錯/日誌 |
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
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]個"
private static final Pattern EMAIL = Pattern.compile(...);Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL)。(a+)+、(.*)* 等嵌套量詞在長字串會指數級回溯,改用佔有優先量詞 (a++)+ 或原子組 (?>...)。Matcher.appendReplacement/appendTail 手動構建,避免 replaceAll 內部創建大量字串。pattern.matcher(input)。掌握 Pattern 編譯複用、matches/lookingAt/find 三模式語義差異、分組提取與位置、find() 迭代、函數式替換 五大核心技能,即能駕馭 95% 正則場景。記住「編譯一次、匹配多次、慎用回溯、函數式替換」八字訣,寫出高效健壯的正則代碼。