package com.ruoyi.im.util; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.HashMap; import java.util.Map; /** * 手机号格式校验工具类 * 支持中国大陆手机号和国际手机号验证 */ public class PhoneNumberValidatorUtil { // 中国大陆手机号正则表达式 (11位数字,1开头) private static final String CHINA_MOBILE_PATTERN = "^1[3-9]\\d{9}$"; // 国际手机号正则表达式 (国家代码-号码,如+1-1234567890) private static final String INTERNATIONAL_PATTERN = "^\\+\\d{1,4}-\\d{4,15}$"; // 常见国家/地区代码映射表 private static final Map COUNTRY_CODES = new HashMap<>(); static { // 初始化常见国家/地区代码 COUNTRY_CODES.put("1", "美国/加拿大"); COUNTRY_CODES.put("86", "中国大陆"); COUNTRY_CODES.put("852", "香港"); COUNTRY_CODES.put("853", "澳门"); COUNTRY_CODES.put("886", "台湾"); COUNTRY_CODES.put("81", "日本"); COUNTRY_CODES.put("82", "韩国"); COUNTRY_CODES.put("65", "新加坡"); COUNTRY_CODES.put("60", "马来西亚"); COUNTRY_CODES.put("44", "英国"); COUNTRY_CODES.put("33", "法国"); COUNTRY_CODES.put("49", "德国"); COUNTRY_CODES.put("61", "澳大利亚"); // 可以继续添加更多国家/地区代码 } /** * 验证手机号格式 * @param phoneNumber 手机号码 * @return 验证结果 */ public static ValidationResult validatePhoneNumber(String phoneNumber) { if (phoneNumber == null || phoneNumber.trim().isEmpty()) { return new ValidationResult(false, "手机号不能为空"); } // 去除可能存在的空格 phoneNumber = phoneNumber.trim(); // 检查是否为中国大陆手机号 if (Pattern.matches(CHINA_MOBILE_PATTERN, phoneNumber)) { return new ValidationResult(true, "中国大陆手机号格式正确"); } // 检查是否为国际手机号格式 if (Pattern.matches(INTERNATIONAL_PATTERN, phoneNumber)) { // 提取国家代码部分 String[] parts = phoneNumber.split("-", 2); String countryCode = parts[0].substring(1); // 去掉+号 // 验证国家代码是否有效 if (COUNTRY_CODES.containsKey(countryCode)) { return new ValidationResult(true, "国际手机号格式正确 (" + COUNTRY_CODES.get(countryCode) + ")"); } else { return new ValidationResult(false, "不支持的国家/地区代码: +" + countryCode); } } // 如果都不匹配,返回错误信息 if (phoneNumber.startsWith("+")) { return new ValidationResult(false, "国际手机号格式不正确,请使用'+国家代码-本地号码'格式"); } else { return new ValidationResult(false, "中国大陆手机号应为11位数字且以1开头"); } } /** * 验证结果类 */ public static class ValidationResult { private final boolean valid; private final String message; public ValidationResult(boolean valid, String message) { this.valid = valid; this.message = message; } public boolean isValid() { return valid; } public String getMessage() { return message; } @Override public String toString() { return message; } } /** * 提取国家代码(如果是国际手机号) * @param phoneNumber 手机号码 * @return 国家代码(不带+号),如果是中国大陆手机号返回"86" */ public static String extractCountryCode(String phoneNumber) { if (phoneNumber == null || phoneNumber.trim().isEmpty()) { return null; } phoneNumber = phoneNumber.trim(); // 如果是国际手机号格式 if (Pattern.matches(INTERNATIONAL_PATTERN, phoneNumber)) { String[] parts = phoneNumber.split("-", 2); return parts[0].substring(1); // 去掉+号 } // 如果是中国大陆手机号 if (Pattern.matches(CHINA_MOBILE_PATTERN, phoneNumber)) { return "86"; } return null; } /** * 提取本地号码部分 * @param phoneNumber 手机号码 * @return 本地号码部分 */ public static String extractLocalNumber(String phoneNumber) { if (phoneNumber == null || phoneNumber.trim().isEmpty()) { return null; } phoneNumber = phoneNumber.trim(); // 如果是国际手机号格式 if (Pattern.matches(INTERNATIONAL_PATTERN, phoneNumber)) { String[] parts = phoneNumber.split("-", 2); return parts[1]; } // 如果是中国大陆手机号 if (Pattern.matches(CHINA_MOBILE_PATTERN, phoneNumber)) { return phoneNumber; } return null; } /** * 格式化手机号显示 * @param phoneNumber 手机号码 * @return 格式化后的手机号 */ public static String formatPhoneNumber(String phoneNumber) { ValidationResult result = validatePhoneNumber(phoneNumber); if (!result.isValid()) { return phoneNumber; // 如果格式不正确,返回原值 } if (Pattern.matches(CHINA_MOBILE_PATTERN, phoneNumber)) { // 中国大陆手机号格式化为 3-4-4 格式 return phoneNumber.replaceFirst("(\\d{3})(\\d{4})(\\d{4})", "$1-$2-$3"); } else if (Pattern.matches(INTERNATIONAL_PATTERN, phoneNumber)) { // 国际手机号保持原格式 return phoneNumber; } return phoneNumber; } // 测试方法 public static void main(String[] args) { // 测试用例 String[] testNumbers = { "13800138000", // 中国大陆手机号 "+1-1234567890", // 美国手机号 "+852-12345678", // 香港手机号 "12345678901", // 无效的中国大陆手机号(不以1开头) "+86-13800138000", // 带国家代码的中国大陆手机号 "+999-1234567890", // 不支持的国家代码 "+1-123", // 号码部分太短 "abc", // 完全无效 "+1-1234567890123456" // 号码部分太长 }; for (String number : testNumbers) { ValidationResult result = validatePhoneNumber(number); System.out.println(number + " : " + result.getMessage()); if (result.isValid()) { System.out.println(" 国家代码: " + extractCountryCode(number)); System.out.println(" 本地号码: " + extractLocalNumber(number)); System.out.println(" 格式化: " + formatPhoneNumber(number)); } System.out.println(); } } }