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<String, String> 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();
|
}
|
}
|
}
|