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

Java 正則表達式實戰(二):四大核心操作與綜合案例詳解

     編輯:Java 相關知識

前言

接上篇《常用符號速查》,本文聚焦正則表達式在 Java 中的四大核心實戰操作——匹配、切割、替換、提取,配合豐富代碼示例與輸出驗證,並以 IP 地址排序綜合案例收尾,助你從「懂語法」進階到「會應用」。

一、四大核心操作 API 概覽

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)

案例 1:按一個或多個空格切割

String str = "aaa bbb  ccc   ddd";
String[] arr = str.split(" +"); // + 表示 1~n 個空格
// 輸出:aaa bbb ccc ddd (無分隔符)

案例 2:按點號 . 切割(需轉義)

String str = "zhangsan.lisi.wangwu";
String[] arr = str.split("\\."); // \\. 表示字面點號
// 輸出:zhangsan / lisi / wangwu
轉義提醒:正則元字符 .$()*+[]?\^{}| 在 split() 中若要表達字面義,必須雙重轉義 \\.(Java 字符串轉義 + 正則轉義)。

案例 3:按重複字符切割(反向引用)

String str = "wer#######tayuio****asdfg";
String[] arr = str.split("(.)\\1+"); // (.) 捕獲任意字符,\\1+ 反向引用 1 次以上
// 輸出:wer / tayuio / asdfg

原理解析:(.) 捕獲第一個字符(如 #),\\1+ 表示「同樣字符重複 1 次以上」,整體匹配連續重複序列作為分隔符。

四、操作三:替換 replaceAll(regex, replacement)

案例 1:將連續重複字符替換為單一 #

String str = "wer#####yw****fghj";
str = str.replaceAll("(.)\\1+", "#");
// 結果:wer#yw#fghj

案例 2:將連續重複字符壓縮為單個(保留一個)

String str = "wer#####yw****fg???hj";
str = str.replaceAll("(.)\\1+", "$1"); // $1 引用第 1 組捕獲內容
// 結果:wer#yw*fg?hj

案例 3:手機號碼中間四位掩碼

String phone = "15889895644";
phone = phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
// 結果:158****5644

替換字符串語法:$n 引用第 n 組捕獲組,$0 代表整個匹配,\\ 轉義字面 $ 或 \。

五、操作四:提取匹配內容 Pattern + Matcher

String 無直接提取 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 組捕獲。

六、綜合實戰案例:IP 地址升序排序

題目:對 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

關鍵步驟解析

  1. replaceAll("(\\d+)", "00$1"):捕獲每段數字,前綴 00 確保至少 3 位。
  2. replaceAll("0*(\\d{3})", "$1"):貪婪匹配前導 0,保留最後 3 位數字,實現定寬對齊。
  3. Arrays.sort():字典序排序即等價數值序(因等寬)。
  4. 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 排序案例展示了「正則預處理 + 標準庫排序 + 正則還原」的組合拳思維,這正是正則表達式作為「文本處理瑞士軍刀」的精髓所在。

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