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

Java 正則表達式實戰指南:基礎語法、String API、Pattern/Matcher 進階與網頁爬蟲郵箱提取完整實作

     編輯:Java 相關知識

Java 正則表達式從入門到實戰:爬蟲郵箱提取完整案例

正則表達式是字串模式匹配利器。Java 提供 String 便利方法與 Pattern/Matcher 核心 API。本文系統整理語法規則、API 用法、常見陷阱,並以網頁郵箱爬蟲為例示範完整實作流程。

String 便利方法 (底層委派 Pattern/Matcher)

方法用途範例
matches(regex)整串匹配 (隱含 ^$)"12345".matches("\\d+") → true
split(regex)分割字串"a,b,c".split(",") → ["a","b","c"]
replaceAll(regex, repl)全域替換"ab12cd".replaceAll("\\d+", "#") → "ab#cd"
replaceFirst(regex, repl)首次替換"ab12cd34".replaceFirst("\\d+", "#") → "ab#cd34"

核心 API:Pattern + Matcher (高效能、功能完整)

// 1. 編譯模式 (可複用、線程安全)
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);

// 2. 建立匹配器 (非線程安全、輸入特定字串)
Matcher matcher = pattern.matcher(inputString);

// 3. 三種匹配模式
// 3.1 整串匹配 (等同 String.matches)
boolean fullMatch = matcher.matches();

// 3.2 尋找子串 (可重複呼叫,配合群組提取)
while (matcher.find()) {
    String full = matcher.group();      // 整個匹配
    String group1 = matcher.group(1);   // 第 1 個捕獲組
    int start = matcher.start();        // 匹配起始索引
    int end = matcher.end();            // 匹配結束索引
}

// 3.3 尋找指定位置開頭匹配
boolean lookingAt = matcher.lookingAt();

正則語法速查表

語法含義範例匹配
.任意字元 (除換行,DOTALL 含換行)a.c → "abc", "axc"
[abc]字元類別 (a 或 b 或 c)[aeiou] → 元音
[^abc]排除字元類別[^0-9] → 非數字
[a-z]範圍[A-Z0-9] → 大寫字母數字
\d數字 [0-9]
\D非數字
\w單字字元 [a-zA-Z0-9_]
\W非單字字元
\s空白字元
\S非空白字元
*0 次或多次 (貪婪)ab*c → "ac", "abc", "abbc"
+1 次或多次ab+c → "abc", "abbc"
?0 次或 1 次ab?c → "ac", "abc"
{n}恰好 n 次\\d{4} → 4 位數字
{n,}至少 n 次\\d{2,} → 2 位以上數字
{n,m}n 到 m 次\\d{3,5} → 3-5 位數字
()捕獲組 (可反向引用 \\1, \\2)(\\w+)\\s+\\1 → 重複單字
(?:)非捕獲組(?:\\d{3}-)?\\d{4} → 區碼可選
|或cat|dog → "cat" 或 "dog"
^行首 (MULTILINE 模式)
$行尾 (MULTILINE 模式)
\\b單字邊界\\bcat\\b → 整字 "cat"

Java 字串中雙重轉義陷阱

// 目標正則: \. (匹配字面點號)
// Java 字串: "\\."  (第一層: \ → \\, 第二層: . → \.)
String regex = "\\."; 

// 目標正則: \\ (匹配字面反斜線)
// Java 字串: "\\\\" (第一層: \ → \\, 第二層: \ → \\)
String regex = "\\\\"; 

// 目標正則: \d+ (匹配數字)
// Java 字串: "\\d+" (僅需轉義反斜線)
String regex = "\\d+";

實戰案例:網頁郵箱爬蟲

import java.io.*;
import java.net.*;
import java.util.regex.*;

public class EmailCrawler {
    // 郵箱正則: 用戶名@域名 (支援多級子域名)
    // 用戶名: 字母數字下劃線 6-12 位
    // 域名: 字母數字 + 多個 .字母 結構
    private static final String EMAIL_REGEX = "[a-zA-Z0-9_]{6,12}@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";
    private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REGEX);
    
    public static void main(String[] args) {
        String urlStr = "https://bbs.example.com/topics/390148495"; // 目標頁面
        String outputFile = "emails.txt";
        
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(new URL(urlStr).openStream(), StandardCharsets.UTF_8));
             BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile))) {
            
            String line;
            int count = 0;
            while ((line = reader.readLine()) != null) {
                Matcher matcher = EMAIL_PATTERN.matcher(line);
                while (matcher.find()) {
                    String email = matcher.group();
                    writer.write(email);
                    writer.newLine();
                    writer.flush(); // 即時寫入
                    count++;
                    System.out.println("發現郵箱 [" + count + "]: " + email);
                }
            }
            System.out.println("爬取完成,共提取 " + count + " 個郵箱,儲存至 " + outputFile);
            
        } catch (MalformedURLException e) {
            System.err.println("無效 URL: " + urlStr);
        } catch (IOException e) {
            System.err.println("網路/IO 錯誤: " + e.getMessage());
        }
    }
}

進階優化與最佳實務

場景優化策略
高效能匹配預編譯 Pattern 靜態常數複用;避免在迴圈中 Pattern.compile
大量文本使用 Matcher.find() 迭代而非 matches();考慮分塊處理
複雜正則啟用 Pattern.COMMENTS 撰寫可讀正則;拆解為多個簡單正則
效能災難避免嵌套量詞 (a+)+、過度回溯;使用佔有優先量詞 ++、*+、?+
Unicode 支援Pattern.UNICODE_CHARACTER_CLASS 讓 \w/\d/\s 支援 Unicode
多行模式Pattern.MULTILINE 讓 ^$ 匹配行首行尾;DOTALL 讓 . 匹配換行

常見郵箱正則進化

// 簡易版 (教學用)
[a-zA-Z0-9_]+@[a-zA-Z0-9]+\\.[a-zA-Z]+

// 實用版 (RFC 5322 簡化)
[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}

// 生產版 (嚴格、長度限制、國際化域名)
^(?=.{1,64}@)[a-zA-Z0-9._%+-]+@(?=.{1,255}$)[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$

// Java 內建驗證 (Jakarta Bean Validation)
@Email // 需依賴 validation-api + hibernate-validator

掌握正則核心語法、Java API 正確用法、效能陷阱規避,配合實戰爬蟲經驗,即可高效解決文本提取、驗證、轉換等核心需求。

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