正则很难做到严谨,更难以维护。这里不讲算法原理,只搬运两个算法来代替正则。
身份证校验-特征组合码
首先从网上粘一个常用的身份证正则,结合一个根本不存在的身份证。
String idRegex = "[1-9]\\d{13,16}[a-zA-Z0-9]{1}";
// 结果校验为true
System.out.println( "999115199005180999".matches(idRegex));
身份号码是特征组合码,由十七位数字本体码和一位校验码组成,详见中华人民共和国国家标准GB 11643-1999
那么可以采用实现了该标准的校验码算法去校验身份证。不仅更加严谨,性能也更佳。
/**
* 校验码算法
*/
private static boolean isValidIdCard(String idCard) {
if (Strings.isNullOrEmpty(idCard)) {
return false;
}
char[] id = idCard.toCharArray();
int i, sum, n;
for (sum = i = 0; i < 17; i++) {
sum += ((1 << (17 - i)) % 11) * (id[i] - '0');
}
n = (12 - (sum % 11)) % 11;
if (n < 10) {
return (n == id[17] - '0');
} else {
return (id[17] == 'X');
}
}
//接下来测试
System.out.println(isValidIdCard("999115199005180999"));
邮箱校验-rfc0822标准
首先从网上粘一则号称企业级实现的正则,再写一个非主流邮箱测试。
String email = "tom&jerry@test.com";
String regex = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
System.out.println(email.matches(regex));
输出结果为false。一般来说主流邮箱网站是不允许注册tom&jerry@test.com这种带特殊符号的邮箱,但有些小众邮箱就是这么有个性。这也意味着一些实际存在的邮箱无法通过校验。
邮箱地址基于 rfc0822标准 ,实际上tom&jerry@test.com是符合rfc0822标准的。与其写出一个面面俱到的正则,不如直接采用内部已经实现了rfc0822标准的 javax.mail.internet.InternetAddress
/**
* javax.mail.internet.InternetAddress 里面的算法实现了rfc0822标准校验
*/
public static boolean isValidEmailAddress(String aEmailAddress) {
if (aEmailAddress == null) {
return false;
}
boolean result = true;
try {
if (!hasNameAndDomain(aEmailAddress)) {
result = false;
}
// 不满足rfc0822标准会抛出"Illegal address" AddressException 异常
new InternetAddress(aEmailAddress);
} catch (AddressException ex) {
// 若抛出异常说明不满足合法邮箱格式
result = false;
}
return result;
}
/**
* 判断是否满足邮箱的基本格式
*/
private static boolean hasNameAndDomain(String aEmailAddress) {
String[] tokens = aEmailAddress.split("@");
return
tokens.length == 2 && !Strings.isNullOrEmpty(tokens[0]) &&
!Strings.isNullOrEmpty(tokens[1])
;
}
当邮箱不满足rfc0822标准会抛出AddressException,这种校验方式效率不高,但比正则严谨。
String email = "tom&jerry@test.com";
// 冷门小众邮箱终于能通过校验了
System.out.println(isValidEmailAddress(email));
依赖
示例使用到的依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>