public class RegexUtil {
public static final String IDCardRegex = "(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}[0-9Xx]$)"
public static final String IDCardRegexWithEmpty = "((^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}[0-9Xx]|$)|(^$))"
public static final String PhoneRegex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\d{8}$"
public static final String PhoneRegexWithEmpty = "(^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\d{8}$|(^$))"
public static final String HomeTelRegex = "^(\+\d{2}-)?0\d{2,3}-\d{7,8}$"
public static final String HomeTelRegexWithEmpty = "(^(\+\d{2}-)?0\d{2,3}-\d{7,8}$|(^$))"
public static final String DateTimeRegex = "^\d{4}-\d{1,2}-\d{1,2}"
public static final String EngineNoRegex = "^([a-zA-Z]|\d){6,20}$"
public static final String EngineNoRegexWithEmpty = "(^([a-zA-Z]|\d){6,20}$)|(^$)"
public static final String BankCardNoRegex = "^\d{19}$"
public static final String CarNumberRegex = "^[京|津|沪|渝|冀|豫|云|辽|晋|湘|皖|鲁|鄂|苏|浙|赣|新|桂|甘|黑|蒙|陕|吉|闽|贵|粤|青|藏|川|宁|琼][A-Za-z][A-Za-z0-9]{5,7}$"
public static final String CarNumberRegexWithEmpty = "(^[京|津|沪|渝|冀|豫|云|辽|晋|湘|皖|鲁|鄂|苏|浙|赣|新|桂|甘|黑|蒙|陕|吉|闽|贵|粤|青|藏|川|宁|琼][A-Za-z][A-Za-z0-9]{5,7}$)|(^$)"
/**
* 身份证号码验证
* 1、号码的结构
* 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,
* 八位数字出生日期码,三位数字顺序码和一位数字校验码。
* 2、地址码(前六位数)
* 表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。
* 3、出生日期码(第七位至十四位)
* 表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。
* 4、顺序码(第十五位至十七位)
* 表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,
* 顺序码的奇数分配给男性,偶数分配给女性。
* 5、校验码(第十八位数)
* (1)十七位数字本体码加权求和公式 S = Sum(Ai * Wi), i = 0, , 16 ,先对前17位数字的权求和
* Ai:表示第i位置上的身份证号码数字值 Wi:表示第i位置上的加权因子 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4
* 2 (2)计算模 Y = mod(S, 11) (3)通过模得到对应的校验码 Y: 0 1 2 3 4 5 6 7 8 9 10 校验码: 1 0
* X 9 8 7 6 5 4 3 2
*/
final static Map<Integer, String> zoneNum = new HashMap<Integer, String>()
final static int[] PARITYBIT = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}
final static int[] POWER_LIST = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
/**
* 校验身份证
* 匹配18位身份证
* @param certificateNumber 身份证号
* @return
*/
/*public static boolean matchCertificateNumber(String certificateNumber){
String regex = "^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$"
return match(regex, certificateNumber)
}*/
static {
zoneNum.put(11, "北京")
zoneNum.put(12, "天津")
zoneNum.put(13, "河北")
zoneNum.put(14, "山西")
zoneNum.put(15, "内蒙古")
zoneNum.put(21, "辽宁")
zoneNum.put(22, "吉林")
zoneNum.put(23, "黑龙江")
zoneNum.put(31, "上海")
zoneNum.put(32, "江苏")
zoneNum.put(33, "浙江")
zoneNum.put(34, "安徽")
zoneNum.put(35, "福建")
zoneNum.put(36, "江西")
zoneNum.put(37, "山东")
zoneNum.put(41, "河南")
zoneNum.put(42, "湖北")
zoneNum.put(43, "湖南")
zoneNum.put(44, "广东")
zoneNum.put(45, "广西")
zoneNum.put(46, "海南")
zoneNum.put(50, "重庆")
zoneNum.put(51, "四川")
zoneNum.put(52, "贵州")
zoneNum.put(53, "云南")
zoneNum.put(54, "西藏")
zoneNum.put(61, "陕西")
zoneNum.put(62, "甘肃")
zoneNum.put(63, "青海")
zoneNum.put(64, "宁夏")
zoneNum.put(65, "新疆")
zoneNum.put(71, "台湾")
zoneNum.put(81, "香港")
zoneNum.put(82, "澳门")
zoneNum.put(91, "国外")
}
/**
* @param regex 正则
* @param str 被校验的字符串
* @return boolean
*/
public static boolean match(String regex, String str) {
if (!StringUtils.checkStringNull(regex) && !StringUtils.checkStringNull(str)) {
Pattern pattern = Pattern.compile(regex)
Matcher matcher = pattern.matcher(str)
if (matcher.matches()) {
return true
}
}
return false
}
/**
* 校验手机号
*
* @param mobil 手机号
* @return
*/
public static boolean matchMobil(String mobil) {
/*String regex = "^[1](([3][0-9])|([4][5,7,9])|([5][4,6,9])|([6][6])|([7][3,5,6,7,8])|([8][0-9])|([9][8,9]))[0-9]{8}$"
return match(regex, mobil)
String regex = "^1[3-9][0-9]{9}$"
return match(regex, mobil)
}
/**
* 校验只能输入汉字
*
* @param str 待校验字符串
* @return
*/
public static boolean matchChinese(String str) {
String regex = "^[\u4e00-\u9fa5]+$"
return match(regex, str)
}
/**
* 校验银行卡号
* 匹配19位数字
*
* @param bankCard 银行卡号
* @return 校验过程:
* 1、从卡号最后一位数字开始,逆向将奇数位(1、3、5等等)相加。
* 2、从卡号最后一位数字开始,逆向将偶数位数字,先乘以2(如果乘积为两位数,将个位十位数字相加,即将其减去9),再求和。
* 3、将奇数位总和加上偶数位总和,结果应该可以被10整除。
*/
public static boolean matchBankCard(String bankCard) {
if (bankCard.length() < 15 || bankCard.length() > 19) {
return false
}
//计算校验位
char bit = getBankCardCheckCode(bankCard.substring(0, bankCard.length() - 1))
if (bit == 'N') {
return false
}
//比较 计算所得的校验位和卡号中的校验位
return bankCard.charAt(bankCard.length() - 1) == bit
}
/**
* 校验银行卡号
* 匹配19位数字
*
* @param bankCard 银行卡号
* @return 校验过程:
* 1、从卡号最后一位数字开始,逆向将奇数位(1、3、5等等)相加。
* 2、从卡号最后一位数字开始,逆向将偶数位数字,先乘以2(如果乘积为两位数,将个位十位数字相加,即将其减去9),再求和。
* 3、将奇数位总和加上偶数位总和,结果应该可以被10整除。
*/
public static boolean matchBankCardWithNull(String bankCard) {
if (StringUtils.checkStringNull(bankCard)) {
return true
}
return matchBankCard(bankCard)
}
/**
* 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位
*
* @param nonCheckCodeBankCard
* @return
*/
public static char getBankCardCheckCode(String nonCheckCodeBankCard) {
if (nonCheckCodeBankCard == null || nonCheckCodeBankCard.trim().length() == 0
|| !nonCheckCodeBankCard.matches("\d+")) {
//如果传的不是数据返回N
return 'N'
}
char[] chs = nonCheckCodeBankCard.trim().toCharArray()
int luhmSum = 0
for (int i = chs.length - 1, j = 0
int k = chs[i] - '0'
if (j % 2 == 0) {//偶数位处理
k *= 2
k = k / 10 + k % 10
}
luhmSum += k
}
return (luhmSum % 10 == 0) ? '0' : (char) ((10 - luhmSum % 10) + '0')
}
/**
* 验证身份证号是否基本有效
*
* @param s 号码内容
* @return 是否有效, null和""都是false
*/
public static boolean matchCertificateNumber(String s) {
if (s == null || (s.length() != 15 && s.length() != 18))
return false
final char[] cs = s.toCharArray()
// (1)校验位数
int power = 0
for (int i = 0
if (i == cs.length - 1 && cs[i] == 'X')
break
if (cs[i] < '0' || cs[i] > '9')
return false
if (i < cs.length - 1)
power += (cs[i] - '0') * POWER_LIST[i]
}
// (2)校验区位码
if (!zoneNum.containsKey(Integer.valueOf(s.substring(0, 2)))) {
return false
}
// (3)校验年份
String year = s.length() == 15 ? "19" + s.substring(6, 8) : s.substring(6, 10)
final int iyear = Integer.parseInt(year)
if (iyear < 1900 || iyear > Calendar.getInstance().get(Calendar.YEAR)) {
return false
}
// (4)校验月份
String month = s.length() == 15 ? s.substring(8, 10) : s.substring(10, 12)
final int imonth = Integer.parseInt(month)
if (imonth < 1 || imonth > 12)
return false
// (5)校验天数
String day = s.length() == 15 ? s.substring(10, 12) : s.substring(12, 14)
final int iday = Integer.parseInt(day)
if (iday < 1 || iday > 31)
return false
// (6)校验一个合法的年月日
if (!validate(iyear, imonth, iday))
return false
// (7)校验“校验码”
if (s.length() == 15)
return true
return cs[cs.length - 1] == PARITYBIT[power % 11]
}
static boolean validate(int year, int month, int day) {
// 比如考虑闰月,大小月等
return true
}
/**
* 匹配发动机号
*
* @param value
* @return
*/
public static Boolean engineNumberMatch(String value) {
String regex = "^([a-zA-Z]|\d){6,20}$"
return match(regex, value)
}
public static Boolean carNumberMatch(String value) {
String regex = "^[京|津|沪|渝|冀|豫|云|辽|晋|湘|皖|鲁|鄂|苏|浙|赣|新|桂|甘|黑|蒙|陕|吉|闽|贵|粤|青|藏|川|宁|琼][A-Za-z][A-Za-z0-9]{5,7}$"
return match(regex, value)
}
//校验正数,两位小数
public static Boolean matchNum(String num) {
String regex = "^(0\.?\d{0,2}|[1-9]\d*\.?\d{0,2})$"
return match(regex, num)
}
//匹配返回圆括号中的文字
public static List<String> getContentFromParentheses(String str){
List<String> list=new ArrayList<>()
String regex = "\((.*?)\)"
Pattern pattern = Pattern.compile(regex)
Matcher matcher = pattern.matcher(str)
while (matcher.find()) {
list.add(matcher.group(1))
}
return list
}
}