接上篇《常用符號速查》,本文聚焦正則表達式在 Java 中的四大核心實戰操作——匹配、切割、替換、提取,配合豐富代碼示例與輸出驗證,並以 IP 地址排序綜合案例收尾,助你從「懂語法」進階到「會應用」。
Java 正則核心類位於 java.util.regex 套件:
Pattern:編譯後的正則模式(不可變、執行緒安全)。Matcher:針對輸入字符串的匹配引擎(狀態機,非執行緒安全)。String 便捷方法:matches()、split()、replaceAll()、replaceFirst()(內部委派 Pattern/Matcher)。matches(regex)驗證整個字符串是否符合規則(隱含 ^...$ 整體匹配)。
String tel = "18600000111";
String regex = "1[3578]\\d{9}"; // 手機號簡易規則
boolean valid = tel.matches(regex); // true
System.out.println(valid);
split(regex)String str = "aaa bbb ccc ddd";
String[] arr = str.split(" +"); // + 表示 1~n 個空格
// 輸出:aaa bbb ccc ddd (無分隔符)
. 切割(需轉義)String str = "zhangsan.lisi.wangwu";
String[] arr = str.split("\\."); // \\. 表示字面點號
// 輸出:zhangsan / lisi / wangwu
轉義提醒:正則元字符.$()*+[]?\^{}|在split()中若要表達字面義,必須雙重轉義\\.(Java 字符串轉義 + 正則轉義)。
String str = "wer#######tayuio****asdfg";
String[] arr = str.split("(.)\\1+"); // (.) 捕獲任意字符,\\1+ 反向引用 1 次以上
// 輸出:wer / tayuio / asdfg
原理解析:(.) 捕獲第一個字符(如 #),\\1+ 表示「同樣字符重複 1 次以上」,整體匹配連續重複序列作為分隔符。
replaceAll(regex, replacement)#String str = "wer#####yw****fghj";
str = str.replaceAll("(.)\\1+", "#");
// 結果:wer#yw#fghj
String str = "wer#####yw****fg???hj";
str = str.replaceAll("(.)\\1+", "$1"); // $1 引用第 1 組捕獲內容
// 結果:wer#yw*fg?hj
String phone = "15889895644";
phone = phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
// 結果:158****5644
替換字符串語法:$n 引用第 n 組捕獲組,$0 代表整個匹配,\\ 轉義字面 $ 或 \。
Pattern + MatcherString 無直接提取 API,需使用 Matcher.find() 迭代。
String text = "da jio zhu yi laa, ming tian fang jia laa";
String regex = "\\b[a-z]{3}\\b"; // 單詞邊界 \b,匹配 3 個字母單詞
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(text);
while (m.find()) {
System.out.printf("start=%d, group=%s, end=%d%n", m.start(), m.group(), m.end());
}
// 輸出:
// start=3, group=jio, end=6
// start=7, group=zhu, end=10
// start=14, group=laa, end=17
// start=35, group=jia, end=38
// start=39, group=laa, end=42
關鍵方法:find() 尋找下一匹配,start()/end() 返回匹配區間,group() 返回匹配文本,group(i) 返回第 i 組捕獲。
題目:對 10.10.10.10 192.168.118.40 192.168.1.200 127.0.0.108 升序排序。
思路:IP 各段位數不定,直接字符串排序錯誤(如 192.168.1.200 < 192.168.118.40)。需補零對齊每段為 3 位,排序後再還原。
public class IpSortDemo {
public static void main(String[] args) {
String ips = "10.10.10.10 192.168.118.40 192.168.1.200 127.0.0.108";
// 1. 每段數字前補 00 → 0010.0010.0010.0010 ...
ips = ips.replaceAll("(\\d+)", "00$1");
// 2. 只保留每段最後 3 位 → 010.010.010.010 ...
ips = ips.replaceAll("0*(\\d{3})", "$1");
// 3. 空格分割、排序
String[] arr = ips.split(" +");
Arrays.sort(arr);
// 4. 還原:移除前導 0
for (String ip : arr) {
System.out.println(ip.replaceAll("0*(\\d+)", "$1"));
}
}
}
10.10.10.10
127.0.0.108
192.168.1.200
192.168.118.40
replaceAll("(\\d+)", "00$1"):捕獲每段數字,前綴 00 確保至少 3 位。replaceAll("0*(\\d{3})", "$1"):貪婪匹配前導 0,保留最後 3 位數字,實現定寬對齊。Arrays.sort():字典序排序即等價數值序(因等寬)。replaceAll("0*(\\d+)", "$1"):還原去除前導 0。() vs [] vs {}| 符號 | 作用 | 示例 |
|---|---|---|
() | 捕獲分組,用於反向引用 \\1、替換 $1、提取 group(1);將子表達式視為整體量化 | (ab)+ 匹配 abab |
[] | 字符類,定義單字符可選範圍 | [a-z] 匹配任意小寫字母 |
{} | 量詞,指定前面單元重複次數 | \\d{3,5} 匹配 3~5 位數字 |
易混淆點:
(0-9) 匹配字面字符串 0-9;[0-9] 匹配任意一個數字。[0-9]* 匹配 0~n 個數字(可空);[0-9]+ 匹配 1~n 個數字(非空)。{1-9} 語法錯誤;正確寫法 {1,9} 或 {1,}。掌握 匹配驗證、切割分隔、替換轉換、提取分析 四大操作,配合 Pattern/Matcher 靈活 API,即可解決 90% 文本處理需求。IP 排序案例展示了「正則預處理 + 標準庫排序 + 正則還原」的組合拳思維,這正是正則表達式作為「文本處理瑞士軍刀」的精髓所在。