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

正則表達式完全手冊:語法精講、Java API 實戰與高性能優化

     編輯:Java 綜合教學

正則表達式完全手冊:語法精講、Java API 實戰與高性能優化

正則表達式是文本處理的瑞士軍刀。本文系統梳理字符類、量詞、邊界、分組捕獲等核心語法,實戰 Java Pattern/Matcher、String 便利方法、預編譯緩存、回溯陷阱優化,附郵箱驗證、敏感詞過濾、日誌解析三大生產案例。

核心語法速查表

分類語法含義示例匹配
字符類[abc]單字符:a/b/ca
[^abc]除 a/b/c 外任意字符d
[a-zA-Z]字母範圍Z
[0-9]數字範圍5
.任意字符(除換行)@
\d \D \w \W \s \S預定義:數字/非數字/單詞/非單詞/空白/非空白\d→8
邊界^ $行首/行尾(多行模式影響)^Hello
\b \B單詞邊界/非邊界\bcat\b
\A \Z \z字符串絕對首/尾(不受多行模式影響)\Astart
量詞?0 或 1 次colou?r
*0 或多次ab*c
+1 或多次ab+c
{n}恰好 n 次\d{3}
{n,m}n 到 m 次\d{2,4}
貪婪/懶惰*? +? ??懶惰模式:盡可能少匹配.*?end
*+ ++ ?+佔有優先模式:不回溯.*+end
(?>...)原子組:禁止回溯(?>\d+)

Java 核心 API 三板斧

1. String 便利方法(簡單場景)

// 匹配整字符串
"abc".matches("\\w+"); // true

// 分割
"192.168.1.1".split("\\."); // [192, 168, 1, 1]

// 替換
"fuck shit".replaceAll("(fuck|shit)", "***"); // "*** ***"

// 獲取(Java 9+)
"abc123def".replaceAll("\\d+", "*"); // "abc*def"

2. Pattern/Matcher 專業模式(複雜/高性能場景)

// 1. 預編譯緩存(關鍵優化)
private static final Pattern EMAIL_PATTERN = 
    Pattern.compile("^[\\w.-]+@[\\w-]+(\\.[\\w-]+)+$");

// 2. Matcher 復用
Matcher matcher = EMAIL_PATTERN.matcher(input);
if (matcher.matches()) { ... }

// 3. 分組捕獲與提取
Pattern logPattern = Pattern.compile(
    "(?

3. 獲取功能:find() + group() 循環

Pattern p = Pattern.compile("\\b\\w{3}\\b"); // 3字母單詞
Matcher m = p.matcher("You may be out of my sight");
while (m.find()) {
    System.out.println(m.group() + " @ [" + m.start() + "," + m.end() + ")");
}
// 輸出: You @ [0,3)  may @ [4,7)  out @ [8,11) ...

三大生產級實戰案例

案例一:RFC 5322 郵箱驗證(簡化版)

private static final Pattern EMAIL = Pattern.compile(
    "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+" +   // local part
    "@" +
    "[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?" + // domain
    "(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$"
);

// 測試
Stream.of("user@example.com", "user.name@sub.domain.cn", "invalid@.com")
      .forEach(e -> System.out.println(e + " → " + EMAIL.matcher(e).matches()));

案例二:敏感詞過濾(DFA/Trie 樹優化版思路)

// 正則版(小規模詞庫)
private static final Pattern SENSITIVE = Pattern.compile(
    "(?i)(fuck|shit|damn|bitch|asshole)"); // (?i) 忽略大小寫

public String filter(String text) {
    return SENSITIVE.matcher(text).replaceAll(m -> 
        "*".repeat(m.group().length()));
}

// 大規模詞庫必須用 Trie/DFA,正則回溯會導致災難性性能

案例三:Nginx 訪問日誌結構化解析

// 典型格式: 192.168.1.1 - - [10/Jan/2024:10:30:45 +0800] "GET /api HTTP/1.1" 200 1234
private static final Pattern NGINX_LOG = Pattern.compile(
    "(?\\d+\\.\\d+\\.\\d+\\.\\d+) " +
    ".*? " +
    "\\[(?

高性能優化鐵律

原則錯誤示範正確做法
預編譯緩存 Pattern循環中 Pattern.compile()static final 常量
避免災難性回溯(.*)* (a+)+用 .*?、(?>...)、具體字符類
優先具體字符類.* 匹配非引號內容[^"]* 零回溯
錨定開頭結尾\\d+ 匹配整行數字^\\d+$ 快速失敗
複用 Matcher每次 pattern.matcher(s)matcher.reset(newInput)
分組命名而非索引m.group(1)m.group("ip") 可維護

Java 9+ 新增 API

// Matcher 結果流
Pattern.compile("\\d+").matcher("a1b22c333")
    .results()
    .map(MatchResult::group)
    .forEach(System.out::println); // 1, 22, 333

// 不可變 Pattern(線程安全,可直接共享)
Pattern p = Pattern.compile("\\d+");

正則表達式寫時只讀,維護地獄。生產環境三原則:預編譯緩存、具體字符類消除回溯、命名分組提升可讀性。複雜文本解析優先考慮專用解析器(JSON/CSV/Log4j),正則僅作輕量提取。

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