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

Java 郵箱格式驗證:正則表達式最佳實踐與常見陷阱

     編輯:Java 相關知識

前言

郵箱驗證是表單校驗的高頻需求。雖然 RFC 5322 定義的完整郵箱語法極其複雜,但實際業務中通常只需覆蓋 99% 的常見格式。本文提供生產可用的正則模式,解析常見錯誤寫法,並給出單元測試建議。

推薦正則模式

// 生產環境推薦:平衡嚴謹度與通用性
private static final String EMAIL_REGEX = 
    "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@" +
    "(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}$";

模式解析

片段含義
^[a-zA-Z0-9_+&*-]+本地部分開頭:字母、數字、底線、+、&、*、-,至少一個
(?:\\.[a-zA-Z0-9_+&*-]+)*允許點號分隔的多段,但不能連續點號、不能以點號開頭/結尾
@必須包含單一 @ 符號
(?:[a-zA-Z0-9-]+\\.)+域名部分:子域名由字母數字連字符組成,以點號結尾,至少一段
[a-zA-Z]{2,}$頂級域名:至少兩個字母

完整驗證工具類

import java.util.regex.Pattern;

public class EmailValidator {
    private static final Pattern EMAIL_PATTERN = Pattern.compile(
        "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@" +
        "(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}$"
    );
    
    /** 驗證郵箱格式 */
    public static boolean isValid(String email) {
        if (email == null || email.length() > 254) return false; // RFC 5321 限制
        return EMAIL_PATTERN.matcher(email).matches();
    }
    
    /** 驗證並標準化(轉小寫、去除首尾空白) */
    public static String normalize(String email) {
        if (email == null) return null;
        String trimmed = email.trim().toLowerCase();
        return isValid(trimmed) ? trimmed : null;
    }
    
    // 單元測試範例
    public static void main(String[] args) {
        String[] valid = {
            "user@example.com", "USER@EXAMPLE.COM", "user.name@sub.domain.com",
            "user+tag@example.co.uk", "user_name@domain.io", "u@x.org"
        };
        String[] invalid = {
            "user@", "@domain.com", "user@.com", "user@domain.",
            "user@domain.c", "user..name@domain.com", ".user@domain.com",
            "user@domain..com", "user@-domain.com", "user@domain-.com",
            "user name@domain.com", "user@domain.com ", " user@domain.com",
            "", "a@b.c", "a@b" // 過短或格式錯誤
        };
        
        System.out.println("=== 應通過 ===");
        for (String e : valid) 
            System.out.printf("%-30s %s%n", e, isValid(e) ? "✓" : "✗ FAIL");
        
        System.out.println("\n=== 應拒絕 ===");
        for (String e : invalid) 
            System.out.printf("%-30s %s%n", e, isValid(e) ? "✗ FALSE PASS" : "✓");
    }
}

常見錯誤寫法與修正

錯誤模式問題修正
\\w+@\\w+\\.\\w+不支援點號、+、-、多級域名、頂級域名超過 3 字符使用上述推薦模式
.+@.+\\..+過於寬鬆,允許空格、多個 @、無效字符限制字符集、錨定開頭結尾
[^@]+@[^@]+\\.[^@]+允許連續點號、開頭結尾點號、特殊字符分段限制字符集
原文範例:\\p{Alpha}\\w{2,15}[@][a-z0-9]{3,}[.]\\p{Lower}{2,}強制首字母為字母、本地部分最長 16 字符、域名最短 3 字符、不支援大寫域名、不支援多級域名移除過度限制,支援國際化域名

進階話題

1. 國際化郵箱(EAI / RFC 6531)

支援 Unicode 本地部分與域名(如 用戶@例子.中國),需使用 \\p{L} 匹配 Unicode 字母,但 Java 正則對 Unicode 屬性支援有限。實際專案建議:

  • 前端/輸入層做基礎格式檢查
  • 後端發送驗證郵件作為最終驗證(唯一可靠方式)

2. 為什麼不建議用正則完整實作 RFC 5322

完整 RFC 5322 正則超過 6000 字符,難以維護,且允許註釋、引號字符串、IP 域名等極少見格式。業務上「發送驗證信」才是真正的驗證。

3. 效能優化

  • 預編譯 Pattern 為靜態常量,避免重複編譯。
  • 先做長度與空值檢查,再執行正則匹配。
  • 高併發場景可考慮 Matcher 物件複用(ThreadLocal)。

線上測試工具推薦

  • Regex101:支援 Java 風味、即時解析、單元測試生成
  • Debuggex:可視化正則圖譜
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved