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

Java 正則表達式完全指南(下):語法詳解與實戰模式庫

     編輯:Java 相關知識

正則元字符完整語法表

量詞與貪婪/非貪婪模式

語法名稱匹配次數貪婪性示例
*零或多0~n貪婪ab*c 匹配 "ac", "abc", "abbc"
+一或多1~n貪婪ab+c 匹配 "abc", "abbc"
?零或一0~1貪婪ab?c 匹配 "ac", "abc"
{n}固定 n 次n貪婪a{3} 匹配 "aaa"
{n,}至少 n 次n~∞貪婪a{2,} 匹配 "aa", "aaa"
{n,m}n 到 m 次n~m貪婪a{1,3} 匹配 "a", "aa", "aaa"
*?零或多0~n非貪婪ab*?c 在 "abbbc" 中匹配 "abc"
+?一或多1~n非貪婪ab+?c 在 "abbbc" 中匹配 "abc"
??零或一0~1非貪婪極少使用
{n,}?至少 n 次n~∞非貪婪盡可能少匹配
{n,m}?n 到 m 次n~m非貪婪盡可能少匹配

定位符與邊界

語法含義示例
^字符串開始(多行模式下行首)^Hello 匹配 "Hello world"
$字符串結束(多行模式下行尾)world$ 匹配 "Hello world"
\b單詞邊界\bcat\b 匹配 "cat" 不匹配 "category"
\B非單詞邊界\Bcat\B 匹配 "category" 中的 "cat"
\A字符串絕對開頭不受多行模式影響
\Z字符串絕對結尾不受多行模式影響
\z字符串絕對結尾(不含末尾換行)最嚴格結尾
\G上次匹配結束位置配合 find() 連續匹配

字符類與預定義字符類

語法含義等價形式
.任意字符(除換行符)[\s\S] 匹配含換行
\d數字[0-9]
\D非數字[^0-9]
\s空白字符[ \t\n\r\f\v]
\S非空白字符[^ \t\n\r\f\v]
\w單詞字符[a-zA-Z0-9_] (Unicode 感知)
\W非單詞字符[^a-zA-Z0-9_]
[abc]字符集合匹配 a/b/c 任一
[^abc]負向字符集合匹配非 a/b/c
[a-z]字符範圍a 到 z
[^a-z]負向範圍非 a-z

分組、捕獲與引用

語法名稱說明
(pattern)捕獲組匹配並編號,可用 $1、\1 反向引用
(?:pattern)非捕獲組僅分組不捕獲,效能更好
(?<name>pattern)命名捕獲組Java 7+ 支援,${name} 引用
\n反向引用引用第 n 個捕獲組
\k<name>命名反向引用引用命名捕獲組

斷言(零寬斷言/環視)

語法名稱方向條件示例
(?=pattern)正向肯定預查向右後面匹配 patternWindows(?=95|98) 匹配 "Windows95" 中的 "Windows"
(?!pattern)正向否定預查向右後面不匹配 patternWindows(?!95|98) 匹配 "Windows3.1" 中的 "Windows"
(?<=pattern)反向肯定預查向左前面匹配 pattern(?<=95|98)Windows 匹配 "95Windows" 中的 "Windows"
(?<!pattern)反向否定預查向左前面不匹配 pattern(?<!95|98)Windows 匹配 "3.1Windows" 中的 "Windows"
關鍵特性:斷言不消耗字符,匹配寬度為零,僅檢查條件。

轉義與特殊構造

語法說明
\轉義元字符:\. 匹配字面點,\\ 匹配反斜槓
\cX控制字符:\cM = 回車符
\xNN十六進制:\x41 = 'A'
\uNNNNUnicode:\u00A9 = ©
\NNN八進制:\040 = 空格
\Q...\E字面量區塊:\Q.*+\E 匹配字面 ".*+"

模式修飾符(嵌入模式)

語法效果等價 Flag
(?i)忽略大小寫Pattern.CASE_INSENSITIVE
(?m)多行模式(^$ 匹配行首尾)Pattern.MULTILINE
(?s)單行模式(. 匹配換行)Pattern.DOTALL
(?x)註釋模式(忽略空白、支援 # 註釋)Pattern.COMMENTS
(?U)Unicode 感知Pattern.UNICODE_CHARACTER_CLASS
(?-i)關閉忽略大小寫局部關閉

組合示例:(?im)^pattern$ 忽略大小寫+多行模式。

常用實戰模式庫(可直接複製使用)

身份證號(中國大陸 18 位)

^(\d{6})(18|19|20)?(\d{2})([01]\d)([0123]\d)(\d{3})(\d|X|x)?$

解析:地址碼(6) + 年份(4) + 月(2) + 日(2) + 順序碼(3) + 校驗碼(1)

手機號(主流號段)

^1[3-9]\d{9}$

涵蓋 13-19 開頭,11 位數字。

郵箱地址(RFC 5322 簡化版)

^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

URL(HTTP/HTTPS)

^https?://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$

IPv4 地址

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

強密碼(8-20位,含大小寫數字特殊符號)

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,20}$

中文字符

^[\u4e00-\u9fa5]+$

日期(YYYY-MM-DD,含閏年簡易校驗)

^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$

Java 代碼最佳實踐

1. 編譯複用 Pattern

// 靜態常量編譯一次,多次復用
private static final Pattern EMAIL_PATTERN = Pattern.compile(
    "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
);

public boolean isValidEmail(String email) {
    return EMAIL_PATTERN.matcher(email).matches();
}

2. Matcher 核心方法

方法用途
matches()整串完全匹配
find()尋找子串匹配,配合 start()/end()/group()
find(int start)從指定位置開始尋找
group(int group)獲取指定捕獲組內容
group(String name)獲取命名捕獲組內容
replaceAll(String)替換所有匹配
replaceFirst(String)替換首個匹配
results()Java 9+ 返回 Stream<MatchResult>

3. 分組提取實戰

String text = "User: zhangsan, Email: zhangsan@example.com";
Pattern p = Pattern.compile("User:\\s*(\\w+),\\s*Email:\\s*([\\w.]+@[\\w.]+)");
Matcher m = p.matcher(text);
if (m.find()) {
    System.out.println("用戶名:" + m.group(1));  // zhangsan
    System.out.println("郵箱:" + m.group(2));    // zhangsan@example.com
}

4. 命名捕獲組(Java 7+)

Pattern p = Pattern.compile("(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})");
Matcher m = p.matcher("2024-01-15");
if (m.matches()) {
    System.out.println(m.group("year"));   // 2024
    System.out.println(m.group("month"));  // 01
    System.out.println(m.group("day"));    // 15
}

效能優化與避坑指南

災難性回溯


// 危險模式:嵌套量詞 + 非匹配輸入
String dangerous = "(a+)+b";
String input = "aaaaaaaaaaaaaaaaaaaaac";  // 無 b 結尾
// 回溯次數指數級爆炸,導致 CPU 100% 假死

解決:使用佔有優先量詞 (a++)+b 或原子組 (?>a+)+b,或重寫邏輯避免嵌套量詞。

預編譯與緩存

  • Pattern.compile() 較重,務必靜態常量復用
  • Java 內部緩存最近 256 個 Pattern(PatternCache),但不應依賴

Unicode 支援

// Java 8+ 預設 Unicode 感知,\w 匹配中文等
// 強制開啟:Pattern.compile(regex, Pattern.UNICODE_CHARACTER_CLASS)

總結

正則表達式是文本處理的利器,掌握核心語法分類——量詞、定位、字符類、分組、斷言、修飾符,配合 Pattern/Matcher API,即可應對 95% 匹配提取場景。記住:預編譯復用、警惕回溯、善用非貪婪與斷言,寫出高效可維護的正則。

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