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

Java 手機號碼驗證:正則表達式最佳實踐與常見坑點

     編輯:Java 程式設計入門

手機號驗證是表單校驗高頻需求。中國大陸號段頻繁變更,硬編碼正則極易過期。本文提供可維護的驗證方案,涵蓋正則寫法、號段維護策略、單元測試與生產環境建議。

基礎正則 (僅供教學參考)

// 僅支援 13/15/18 開頭,已過時
Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");

缺點:漏掉 14、16、17、19 等新號段;[^4,\\D] 寫法易誤解;無法應對未來擴展。

可維護驗證器設計

2.1 號段資料外部化

public class MobileValidator {
    // 從配置中心/資料庫載入,支援熱更新
    private static final Set VALID_PREFIXES = new HashSet<>(Arrays.asList(
        "130","131","132","133","134","135","136","137","138","139",
        "147","149","150","151","152","153","155","156","157","158","159",
        "166","170","171","172","173","174","175","176","177","178",
        "180","181","182","183","184","185","186","187","188","189",
        "190","191","192","193","195","196","197","198","199"
    ));

    private static final Pattern FORMAT_PATTERN = Pattern.compile("^1\\d{10}$");

    public static boolean isValid(String mobile) {
        if (mobile == null) return false;
        if (!FORMAT_PATTERN.matcher(mobile).matches()) return false;
        return VALID_PREFIXES.contains(mobile.substring(0, 3));
    }
}

2.2 優點

  • 易維護:新增號段只需更新 Set,無需修改正則、重新編譯。
  • 效能佳:先用簡單正則過濾格式,再 O(1) 查詢前綴。
  • 可測試:單元測試覆蓋邊界值、新舊號段。

單元測試範例 (JUnit 5)

@ParameterizedTest
@CsvSource({
    "13800138000, true",   // 經典號段
    "19988889999, true",   // 新號段
    "12000000000, false",  // 錯誤前綴
    "1380013800, false",   // 10 位
    "138001380000, false", // 12 位
    "abcdefghijk, false",  // 非數字
    ", false",             // 空字串
    "null, false"          // null
})
void testMobile(String input, boolean expected) {
    assertEquals(expected, MobileValidator.isValid(input));
}

生產環境進階建議

  1. 配置中心管理號段:使用 Nacos/Apollo/Zookeeper 存儲 valid.prefixes,應用啟動時載入並監聽變更。
  2. 整合 Bean Validation:
    @Target({FIELD, METHOD, PARAMETER})
    @Retention(RUNTIME)
    @Constraint(validatedBy = MobileValidator.class)
    public @interface ValidMobile {
        String message() default "手機號格式不正確";
        Class[] groups() default {};
        Class[] payload() default {};
    }
    
    public class MobileValidator implements ConstraintValidator {
        @Override public boolean isValid(String value, ConstraintValidatorContext context) {
            return MobileValidator.isValid(value);
        }
    }
    
    // 使用
    public class UserDTO {
        @ValidMobile
        private String mobile;
    }
    
  3. 前後端一致性:前端同樣維護號段白名單或調用後端 API 校驗,避免重複邏輯。
  4. 國際化支援:若需支援港澳台/海外號碼,建議引入 Google libphonenumber 庫:
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
PhoneNumber number = util.parse(phone, "CN"); // 或 "HK", "US"
boolean valid = util.isValidNumber(number);

常見錯誤避坑指南

錯誤寫法問題修正
^1[3-9]\\d{9}$過於寬鬆,允許 140、160 等未分配段白名單前綴
Pattern.compile(...) 在方法內每次調用編譯正則,效能差靜態常量編譯一次
未處理 null/空白拋 NPE 或誤判首行防御性檢查
只驗證格式不驗證號段偽造號碼通過雙重校驗:格式 + 前綴
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved