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

Java 正則表達式完整教學:Pattern/Matcher 核心 API、常用語法、分組捕獲與實戰範例

     編輯:Java 相關知識

前言

自 JDK 1.4 引入 java.util.regex 套件,Java 終於擁有原生、強大且標準化的正則表達式引擎。本文從核心類別 Pattern、Matcher 切入,系統講解語法元素、分組捕獲、貪婪/勉強模式、常用實戰範例(電話號碼、Email、HTML 標籤),並提供效能優化與避坑指南。

一、核心類別架構

  • Pattern:正則表達式的編譯後表示,不可變、執行緒安全,透過 Pattern.compile(regex) 取得。
  • Matcher:執行匹配操作的引擎,透過 pattern.matcher(input) 取得,非執行緒安全。
  • PatternSyntaxException:編譯階段語法錯誤拋出的非受檢異常。

二、基本使用流程

import java.util.regex.*;

public class RegexDemo {
    public static void main(String[] args) {
        // 1. 編譯模式(建議複用 Pattern 實例)
        Pattern pattern = Pattern.compile("\\(\\d{3}\\)\\s?\\d{3}-\\d{4}");

        // 2. 取得匹配器
        Matcher matcher = pattern.matcher("(212) 555-1212");

        // 3. 執行匹配
        if (matcher.find()) {
            System.out.println("完整匹配: " + matcher.group());      // (212) 555-1212
            System.out.println("第1組: " + matcher.group(1));        // 若有捕獲組
        }

        // 4. 替換操作
        String replaced = matcher.replaceAll("[PHONE]");
    }
}

三、Java 正則語法速查表

分類符號說明範例
字元類別.任意單一字元(預設不含換行)a.c 匹配 abc, axc
\d數字 [0-9]\d{3} 三位數
\D非數字
\s空白字元(空格、Tab、換行)
\S非空白
[abc] / [^abc]字元集合 / 排除集合[aeiou] 母音
數量詞?0 或 1 次\d?
*0 或多次(貪婪)ab*c 匹配 ac, abc, abbc...
+1 或多次(貪婪)
{n,m}n 到 m 次\d{3,5}
邊界^行首(多行模式 Pattern.MULTILINE)
$行尾
\b單字邊界\bcat\b 不匹配 "catfish"
分組與引用(...)捕獲組,可用 group(i) 取得(\d{4})-(\d{2})
(?:...)非捕獲組(僅分組不儲存)(?:\d{3})?-
\1, \2...反向引用(匹配前面第 n 組內容)(\w+)\s+\1 匹配重複單字
模式修飾符Pattern.CASE_INSENSITIVE忽略大小寫Pattern.compile("abc", Pattern.CASE_INSENSITIVE)
Pattern.MULTILINE^$ 匹配行首尾
Pattern.DOTALL. 匹配含換行

四、實戰範例:電話號碼多格式匹配

需求:支援 (212) 555-1212、212-555-1212、212 555 1212、2125551212。

// 1. 區碼可選括號、可選空格、分隔符可為 - 或空格或無
String regex = "(\\(\\d{3}\\)|\\d{3})[\\s-]?\\d{3}[\\s-]?\\d{4}";

Pattern p = Pattern.compile(regex);
String[] tests = {
    "(212) 555-1212", "212-555-1212", "212 555 1212", "2125551212",
    "212-5551212", "(212)555-1212"
};

for (String s : tests) {
    Matcher m = p.matcher(s);
    System.out.println(s + " -> " + (m.matches() ? "匹配" : "不匹配"));
}

輸出:

(212) 555-1212 -> 匹配
212-555-1212 -> 匹配
212 555 1212 -> 匹配
2125551212 -> 匹配
212-5551212 -> 匹配
(212)555-1212 -> 匹配

五、進階技巧

  1. 分組提取與替換:matcher.group(1) 取得區碼,matcher.replaceAll("$1-$2-$3") 格式化。
  2. Pattern.split():Pattern.compile("\\s*,\\s*").split("a, b ,c") → [a, b, c]。
  3. Quote 字面字串:Pattern.quote("$1.50") 自動轉義特殊字元。
  4. 效能優化:
    - 預編譯 Pattern 為 static final 常數,避免重複編譯。
    - 避免過度嵌套量詞(如 (a+)+)導致災難性回溯。
    - 長字串分割用 matcher.find() 迴圈而非 split()。

六、常見陷阱與避坑

陷阱原因解法
雙反斜線 \\\\Java 字串字面值需轉義,正則引擎再解析一次習慣寫 \\d、\\.、\\\\;或用 Pattern.quote()
matches() vs find()matches() 需整串匹配,find() 尋找子串全匹配用 matches(),搜尋用 find()
貪婪匹配吃掉分隔符.* 會吞掉後續內容改用勉強模式 .*? 或明確字元集 [^,]*
群組索引從 1 開始group(0) 為整體匹配捕獲組用 group(1) 起

七、結語

Java 正則表達式功能強大且標準化,掌握 Pattern/Matcher 雙核心、熟悉語法元素與修飾符、養成預編譯與勉強模式習慣,即能輕鬆應對複雜字串解析、驗證、提取與替換需求。建議收藏本文語法速查表,實戰中隨查隨用。

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