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

Java 正則表達式完整指南:語法、常用模式與實戰技巧

     編輯:Java 綜合教學

Java 正則表達式完整指南:語法、常用模式與實戰技巧

正則表達式是文本處理的瑞士軍刀。Java 透過 `java.util.regex` 套件提供強大的正則支援。本文系統整理核心語法、常用模式與最佳實踐,助你高效驗證、提取、替換文本。

一、核心類與基礎 API

import java.util.regex.Pattern;
import java.util.regex.Matcher;

// 1. 編譯模式 (建議複用 Pattern,線程安全)
Pattern pattern = Pattern.compile(regex);

// 2. 建立匹配器 (非線程安全,每次匹配新建)
Matcher matcher = pattern.matcher(input);

// 3. 常用匹配操作
boolean matches = matcher.matches();        // 整個輸入完全匹配
boolean find = matcher.find();              // 尋找下一個子序列匹配
boolean lookingAt = matcher.lookingAt();    // 從開頭匹配

// 4. 獲取匹配內容
if (matcher.find()) {
    String group = matcher.group();         // 完整匹配
    String group1 = matcher.group(1);       // 第 1 個捕獲組
    int start = matcher.start();            // 匹配起始索引
    int end = matcher.end();                // 匹配結束索引
}

// 5. 替換操作
String replaced = matcher.replaceAll(replacement);      // 替換所有
String replacedFirst = matcher.replaceFirst(replacement); // 替換首個

// 6. 靜態便捷方法 (適合一次性使用)
boolean b = Pattern.matches(regex, input);
String[] split = Pattern.compile(regex).split(input);
String replaced = input.replaceAll(regex, replacement);

二、核心語法速查表

字符類

語法說明範例
.任意單字符 (除換行符,DOTALL 模式含換行)a.c 匹配 "abc", "a-c"
\d數字 [0-9]\d{3} 匹配 "123"
\D非數字 [^0-9]
\w單詞字符 [a-zA-Z0-9_]
\W非單詞字符
\s空白字符 (空格、Tab、換行等)
\S非空白字符
[abc]字符集合:a 或 b 或 c[aeiou] 元音
[^abc]否定字符集合[^0-9] 非數字
[a-z]範圍:a 到 z[A-Za-z] 字母

數量詞 (貪婪/懶惰/佔有)

貪婪 (預設)懶惰 (加 ?)佔有 (加 +)說明
**?*+0 或多次
++?++1 或多次
????+0 或 1 次
{n}{n}?{n}+恰好 n 次
{n,}{n,}?{n,}+至少 n 次
{n,m}{n,m}?{n,m}+n 到 m 次

原則:預設貪婪匹配盡可能多;懶惰匹配盡可能少;佔有匹配不回溯,效能最佳但可能導致匹配失敗。

邊界與錨點

  • ^:行開頭 (多行模式 MULTILINE 下)
  • $:行結尾
  • \b:單詞邊界
  • \B:非單詞邊界
  • \A:字符串開頭 (不受多行模式影響)
  • \Z:字符串結尾 (允許末尾換行)
  • \z:字符串絕對結尾

分組與引用

  • (...):捕獲組,可用 `group(i)` 或 `$i` 反向引用。
  • (?:...):非捕獲組,僅分組不捕獲,效能較好。
  • (?<name>...):命名捕獲組 (Java 7+),用 `group("name")` 獲取。
  • \1, \2...:正則內反向引用前面的捕獲組。

斷言 (零寬斷言)

模式標記

// 單行模式:. 匹配含換行
Pattern.compile(regex, Pattern.DOTALL); 

// 多行模式:^ $ 匹配每行開頭結尾
Pattern.compile(regex, Pattern.MULTILINE); 

// 忽略大小寫
Pattern.compile(regex, Pattern.CASE_INSENSITIVE); 

// 註釋模式:忽略空白,允許 # 註釋
Pattern.compile(regex, Pattern.COMMENTS); 

// Unicode 感知大小寫
Pattern.compile(regex, Pattern.UNICODE_CASE); 

// 組合使用
Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);

三、實戰常用模式庫

1. 基礎驗證

// Email (簡化版,RFC 5322 完整版極其複雜)
^[\\w.-]+@[\\w-]+(\\.[\\w-]+)+$

// 手機號 (中國大陸)
^1[3-9]\\d{9}$

// 身份證號 (18位,含校驗碼邏輯需代碼實現)
^[1-9]\\d{5}(19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[\\dXx]$

// IP 地址 (IPv4)
^((25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d?\\d)$

// URL
^(https?|ftp)://[^\\s/$.?#].[^\\s]*$

// 日期 (YYYY-MM-DD)
^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$

2. 提取與解析

// 提取 HTML 標籤屬性
<(\\w+)[^>]*?\\s(\\w+)=["']([^"']*)["']

// 提取 URL 域名
https?://([^/]+)

// 提取 Java 包名/類名
package\\s+([\\w.]+);|class\\s+(\\w+)

// 分割 CamelCase: "UserName" → ["User", "Name"]
(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])

3. 替換與清洗

// 移除 HTML 標籤
html.replaceAll("<[^>]*>", "")

// 多空白合併為單空格
text.replaceAll("\\s+", " ")

// 隱藏手機中間4位
phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")

// 轉義正則特殊字符 (用於字面量匹配)
Pattern.quote(literalString)

四、效能優化黃金法則

  1. 預編譯複用 Pattern:`Pattern` 線程安全,編譯昂貴,靜態常量或緩存複用。
  2. 避免過度回溯:慎用嵌套數量詞 `(a+)+`、交替分支中的公共前綴。改用佔有量詞 `++`、`*+` 或原子組 `(?>...)`。
  3. 錨點前置:模式以 `^` 或 `\A` 開頭,能快速失敗。
  4. 具體化字符類:用 `[a-f0-9]` 代替 `.`,減少嘗試。
  5. 非捕獲組:不需反向引用時用 `(?:...)`。
  6. 適度使用 `find()` 代替 `matches()`:`matches()` 需匹配整串,`find()` 尋找子串更快。

五、進階技巧:Pattern 與 Matcher 進階用法

1. 分組引用替換

// 格式化電話: "1234567890" → "(123) 456-7890"
String formatted = phone.replaceAll("(\\d{3})(\\d{3})(\\d{4})", "($1) $2-$3");

2. 使用 Matcher.appendReplacement/appendTail 精細控制替換

StringBuffer sb = new StringBuffer();
while (matcher.find()) {
    // 根據匹配內容動態決定替換字符串
    String replacement = computeReplacement(matcher.group());
    matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
}
matcher.appendTail(sb);
String result = sb.toString();

3. 解析鍵值對 (如 URL 參數、配置檔)

Pattern p = Pattern.compile("(\\w+)=([^&]*)");
Matcher m = p.matcher(queryString);
Map params = new LinkedHashMap<>();
while (m.find()) {
    params.put(m.group(1), URLDecoder.decode(m.group(2), "UTF-8"));
}

六、推薦線上測試工具

  • Regex101:支援 Java 味道,即時解釋、測試、生成代碼片段。
  • RegExr:視覺化高亮、社區模式庫。
  • IDE 內建正則測試器 (IntelliJ IDEA: Ctrl+Alt+R / Cmd+Opt+R)。

正則表達式功能強大但「寫時易讀、改時難懂」。建議:複雜正則必加註釋,使用 `Pattern.COMMENTS` 模式或拆分為多行字符串並附上範例輸入/輸出。掌握核心語法與優化原則,讓正則成為你手中得心應手的利器。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
語法名稱條件
(?=...)正向前瞻後面匹配 ...
(?!...)負向前瞻後面不匹配 ...
(?<=...)正向後顧前面匹配 ... (固定長度)
(?<!...)負向後顧前面不匹配 ... (固定長度)