cn.hutool.core.lang.PatternPool Maven / Gradle / Ivy
package cn.hutool.core.lang;
import cn.hutool.core.map.WeakConcurrentMap;
import java.util.regex.Pattern;
/**
* 常用正则表达式集合,更多正则见:
* https://any86.github.io/any-rule/
*
* @author Looly
*/
public class PatternPool {
/**
* 英文字母 、数字和下划线
*/
public final static Pattern GENERAL = Pattern.compile(RegexPool.GENERAL);
/**
* 数字
*/
public final static Pattern NUMBERS = Pattern.compile(RegexPool.NUMBERS);
/**
* 字母
*/
public final static Pattern WORD = Pattern.compile(RegexPool.WORD);
/**
* 单个中文汉字
*/
public final static Pattern CHINESE = Pattern.compile(RegexPool.CHINESE);
/**
* 中文汉字
*/
public final static Pattern CHINESES = Pattern.compile(RegexPool.CHINESES);
/**
* 分组
*/
public final static Pattern GROUP_VAR = Pattern.compile(RegexPool.GROUP_VAR);
/**
* IP v4
*/
public final static Pattern IPV4 = Pattern.compile(RegexPool.IPV4);
/**
* IP v6
*/
public final static Pattern IPV6 = Pattern.compile(RegexPool.IPV6);
/**
* 货币
*/
public final static Pattern MONEY = Pattern.compile(RegexPool.MONEY);
/**
* 邮件,符合RFC 5322规范,正则来自:http://emailregex.com/
* https://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address/44317754
* 注意email 要宽松一点。比如 [email protected]、jetz-chong@ hutool.cn、[email protected]、[email protected] 宽松一点把,都算是正常的邮箱
*/
public final static Pattern EMAIL = Pattern.compile(RegexPool.EMAIL, Pattern.CASE_INSENSITIVE);
/**
* 规则同EMAIL,添加了对中文的支持
*/
public final static Pattern EMAIL_WITH_CHINESE = Pattern.compile(RegexPool.EMAIL_WITH_CHINESE,Pattern.CASE_INSENSITIVE);
/**
* 移动电话
*/
public final static Pattern MOBILE = Pattern.compile(RegexPool.MOBILE);
/**
* 中国香港移动电话
* eg: 中国香港: +852 5100 4810, 三位区域码+10位数字, 中国香港手机号码8位数
* eg: 中国大陆: +86 180 4953 1399,2位区域码标示+13位数字
* 中国大陆 +86 Mainland China
* 中国香港 +852 Hong Kong
* 中国澳门 +853 Macao
* 中国台湾 +886 Taiwan
*/
public final static Pattern MOBILE_HK = Pattern.compile(RegexPool.MOBILE_HK);
/**
* 中国台湾移动电话
* eg: 中国台湾: +886 09 60 000000, 三位区域码+号码以数字09开头 + 8位数字, 中国台湾手机号码10位数
* 中国台湾 +886 Taiwan 国际域名缩写:TW
*/
public final static Pattern MOBILE_TW = Pattern.compile(RegexPool.MOBILE_TW);
/**
* 中国澳门移动电话
* eg: 中国台湾: +853 68 00000, 三位区域码 +号码以数字6开头 + 7位数字, 中国台湾手机号码8位数
* 中国澳门 +853 Macao 国际域名缩写:MO
*/
public final static Pattern MOBILE_MO = Pattern.compile(RegexPool.MOBILE_MO);
/**
* 座机号码
*/
public final static Pattern TEL = Pattern.compile(RegexPool.TEL);
/**
* 座机号码+400+800电话
*
* @see 800
*/
public final static Pattern TEL_400_800 = Pattern.compile(RegexPool.TEL_400_800);
/**
* 18位身份证号码
*/
public final static Pattern CITIZEN_ID = Pattern.compile(RegexPool.CITIZEN_ID);
/**
* 邮编,兼容港澳台
*/
public final static Pattern ZIP_CODE = Pattern.compile(RegexPool.ZIP_CODE);
/**
* 生日
*/
public final static Pattern BIRTHDAY = Pattern.compile(RegexPool.BIRTHDAY);
/**
* URL
*/
public final static Pattern URL = Pattern.compile(RegexPool.URL);
/**
* Http URL
*/
public final static Pattern URL_HTTP = Pattern.compile(RegexPool.URL_HTTP, Pattern.CASE_INSENSITIVE);
/**
* 中文字、英文字母、数字和下划线
*/
public final static Pattern GENERAL_WITH_CHINESE = Pattern.compile(RegexPool.GENERAL_WITH_CHINESE);
/**
* UUID
*/
public final static Pattern UUID = Pattern.compile(RegexPool.UUID, Pattern.CASE_INSENSITIVE);
/**
* 不带横线的UUID
*/
public final static Pattern UUID_SIMPLE = Pattern.compile(RegexPool.UUID_SIMPLE);
/**
* MAC地址正则
*/
public static final Pattern MAC_ADDRESS = Pattern.compile(RegexPool.MAC_ADDRESS, Pattern.CASE_INSENSITIVE);
/**
* 16进制字符串
*/
public static final Pattern HEX = Pattern.compile(RegexPool.HEX);
/**
* 时间正则
*/
public static final Pattern TIME = Pattern.compile(RegexPool.TIME);
/**
* 中国车牌号码(兼容新能源车牌)
*/
public final static Pattern PLATE_NUMBER = Pattern.compile(RegexPool.PLATE_NUMBER);
/**
* 统一社会信用代码
*
* 第一部分:登记管理部门代码1位 (数字或大写英文字母)
* 第二部分:机构类别代码1位 (数字或大写英文字母)
* 第三部分:登记管理机关行政区划码6位 (数字)
* 第四部分:主体标识码(组织机构代码)9位 (数字或大写英文字母)
* 第五部分:校验码1位 (数字或大写英文字母)
*
*/
public static final Pattern CREDIT_CODE = Pattern.compile(RegexPool.CREDIT_CODE);
/**
* 车架号(车辆识别代号由世界制造厂识别代号(WMI、车辆说明部分(VDS)车辆指示部分(VIS)三部分组成,共 17 位字码。)
* 别名:车辆识别代号、车辆识别码、车架号、十七位码
* 标准号:GB 16735-2019
* 标准官方地址:https://openstd.samr.gov.cn/bzgk/gb/newGbInfo?hcno=E2EBF667F8C032B1EDFD6DF9C1114E02
* 对年产量大于或等于1 000 辆的完整车辆和/或非完整车辆制造厂:
*
* 第一部分为世界制造厂识别代号(WMI),3位
* 第二部分为车辆说明部分(VDS), 6位
* 第三部分为车辆指示部分(VIS), 8位
*
*
* 对年产量小于 1 000 辆的完整车辆和/或非完整车辆制造厂:
*
* 第一部分为世界制造广识别代号(WMI),3位;
* 第二部分为车辆说明部分(VDS),6位;
* 第三部分的三、四、五位与第一部分的三位字码起构成世界制造厂识别代号(WMI),其余五位为车辆指示部分(VIS),8位。
*
*
*
* eg:LDC613P23A1305189
* eg:LSJA24U62JG269225
* eg:LBV5S3102ESJ25655
*
*/
public static final Pattern CAR_VIN = Pattern.compile(RegexPool.CAR_VIN);
/**
* 驾驶证 别名:驾驶证档案编号、行驶证编号
* eg:430101758218
* 12位数字字符串
* 仅限:中国驾驶证档案编号
*/
public static final Pattern CAR_DRIVING_LICENCE = Pattern.compile(RegexPool.CAR_DRIVING_LICENCE);
/**
* 中文姓名
* 总结中国人姓名:2-60位,只能是中文和 ·
*/
public static final Pattern CHINESE_NAME = Pattern.compile(RegexPool.CHINESE_NAME);
// -------------------------------------------------------------------------------------------------------------------------------------------------------------------
/**
* Pattern池
*/
private static final WeakConcurrentMap POOL = new WeakConcurrentMap<>();
/**
* 先从Pattern池中查找正则对应的{@link Pattern},找不到则编译正则表达式并入池。
*
* @param regex 正则表达式
* @return {@link Pattern}
*/
public static Pattern get(String regex) {
return get(regex, 0);
}
/**
* 先从Pattern池中查找正则对应的{@link Pattern},找不到则编译正则表达式并入池。
*
* @param regex 正则表达式
* @param flags 正则标识位集合 {@link Pattern}
* @return {@link Pattern}
*/
public static Pattern get(String regex, int flags) {
final RegexWithFlag regexWithFlag = new RegexWithFlag(regex, flags);
return POOL.computeIfAbsent(regexWithFlag, (key)-> Pattern.compile(regex, flags));
}
/**
* 移除缓存
*
* @param regex 正则
* @param flags 标识
* @return 移除的{@link Pattern},可能为{@code null}
*/
public static Pattern remove(String regex, int flags) {
return POOL.remove(new RegexWithFlag(regex, flags));
}
/**
* 清空缓存池
*/
public static void clear() {
POOL.clear();
}
// ---------------------------------------------------------------------------------------------------------------------------------
/**
* 正则表达式和正则标识位的包装
*
* @author Looly
*/
private static class RegexWithFlag {
private final String regex;
private final int flag;
/**
* 构造
*
* @param regex 正则
* @param flag 标识
*/
public RegexWithFlag(String regex, int flag) {
this.regex = regex;
this.flag = flag;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + flag;
result = prime * result + ((regex == null) ? 0 : regex.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
RegexWithFlag other = (RegexWithFlag) obj;
if (flag != other.flag) {
return false;
}
if (regex == null) {
return other.regex == null;
} else {
return regex.equals(other.regex);
}
}
}
}