最近测试报了很多这样的bug说是身份证正则表达式不够准确仅仅限制了15和18位没有准确的表示出身份证的真真组成的原理,很是头疼,幸亏大神很快的解决了这个问题,下面来看看吧!
直接上代码了
1 public class IDCardUtils { 2 /** 3 * 身份证号码正则表达式 4 */ 5 public static boolean isIDCard(String idNum) throws ParseException { 6 //定义判别用户身份证号的正则表达式(要么是15位,要么是18位,最后一位可以为字母) 7 // Pattern idNumPattern = Pattern.compile("(\\d{14}[0-9a-zA-Z])|(\\d{17}[0-9a-zA-Z])"); 8 // //通过Pattern获得Matcher 9 // Matcher idNumMatcher = idNumPattern.matcher(idNum); 10 // return idNumMatcher.matches(); 11 String[] ValCodeArr = { "1", "0", "x", "9", "8", "7", "6", "5", "4", 12 "3", "2" }; 13 String[] Wi = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", 14 "9", "10", "5", "8", "4", "2" }; 15 String Ai = ""; 16 // ================ 号码的长度 15位或18位 ================ 17 if (idNum.length() != 15 && idNum.length() != 18) { 18 return false; 19 } 20 // =======================(end)======================== 21 22 // ================ 数字 除最后以为都为数字 ================ 23 if (idNum.length() == 18) { 24 Ai = idNum.substring(0, 17); 25 } else if (idNum.length() == 15) { 26 Ai = idNum.substring(0, 6) + "19" + idNum.substring(6, 15); 27 } 28 if (isNumeric(Ai) == false) { 29 return false; 30 } 31 // =======================(end)======================== 32 33 // ================ 出生年月是否有效 ================ 34 String strYear = Ai.substring(6, 10);// 年份 35 String strMonth = Ai.substring(10, 12);// 月份 36 String strDay = Ai.substring(12, 14);// 月份 37 if (isDataFormat(strYear + "-" + strMonth + "-" + strDay) == false) { 38 return false; 39 } 40 GregorianCalendar gc = new GregorianCalendar(); 41 SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd"); 42 if ((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150 43 || (gc.getTime().getTime() - s.parse( 44 strYear + "-" + strMonth + "-" + strDay).getTime()) < 0) { 45 return false; 46 } 47 if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) { 48 return false; 49 } 50 if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) { 51 return false; 52 } 53 // =====================(end)===================== 54 55 // ================ 地区码时候有效 ================ 56 Hashtable h = GetAreaCode(); 57 if (h.get(Ai.substring(0, 2)) == null) { 58 return false; 59 } 60 // ============================================== 61 62 // ================ 判断最后一位的值 ================ 63 int TotalmulAiWi = 0; 64 for (int i = 0; i < 17; i++) { 65 TotalmulAiWi = TotalmulAiWi 66 + Integer.parseInt(String.valueOf(Ai.charAt(i))) 67 * Integer.parseInt(Wi[i]); 68 } 69 int modValue = TotalmulAiWi % 11; 70 String strVerifyCode = ValCodeArr[modValue]; 71 Ai = Ai + strVerifyCode; 72 73 if (idNum.length() == 18) { 74 if (Ai.equals(idNum) == false) { 75 return false; 76 } 77 } else { 78 return false; 79 } 80 return true; 81 82 } 83 84 85 /** 86 * 功能:判断字符串是否为数字 87 * @param str 88 * @return 89 */ 90 private static boolean isNumeric(String str) { 91 Pattern pattern = Pattern.compile("[0-9]*"); 92 Matcher isNum = pattern.matcher(str); 93 if (isNum.matches()) { 94 return true; 95 } else { 96 return false; 97 } 98 } 99 100 /** 101 * 功能:设置地区编码 102 * @return Hashtable 对象 103 */ 104 private static Hashtable GetAreaCode() { 105 Hashtable hashtable = new Hashtable(); 106 hashtable.put("11", "北京"); 107 hashtable.put("12", "天津"); 108 hashtable.put("13", "河北"); 109 hashtable.put("14", "山西"); 110 hashtable.put("15", "内蒙古"); 111 hashtable.put("21", "辽宁"); 112 hashtable.put("22", "吉林"); 113 hashtable.put("23", "黑龙江"); 114 hashtable.put("31", "上海"); 115 hashtable.put("32", "江苏"); 116 hashtable.put("33", "浙江"); 117 hashtable.put("34", "安徽"); 118 hashtable.put("35", "福建"); 119 hashtable.put("36", "江西"); 120 hashtable.put("37", "山东"); 121 hashtable.put("41", "河南"); 122 hashtable.put("42", "湖北"); 123 hashtable.put("43", "湖南"); 124 hashtable.put("44", "广东"); 125 hashtable.put("45", "广西"); 126 hashtable.put("46", "海南"); 127 hashtable.put("50", "重庆"); 128 hashtable.put("51", "四川"); 129 hashtable.put("52", "贵州"); 130 hashtable.put("53", "云南"); 131 hashtable.put("54", "西藏"); 132 hashtable.put("61", "陕西"); 133 hashtable.put("62", "甘肃"); 134 hashtable.put("63", "青海"); 135 hashtable.put("64", "宁夏"); 136 hashtable.put("65", "新疆"); 137 hashtable.put("71", "台湾"); 138 hashtable.put("81", "香港"); 139 hashtable.put("82", "澳门"); 140 hashtable.put("91", "国外"); 141 return hashtable; 142 } 143 144 /**验证日期字符串是否是YYYY-MM-DD格式 145 * @param str 146 * @return 147 */ 148 public static boolean isDataFormat(String str){ 149 boolean flag=false; 150 //String regxStr="[1-9][0-9]{3}-[0-1][0-2]-((0[1-9])|([12][0-9])|(3[01]))"; 151 String regxStr="^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$"; 152 Pattern pattern1=Pattern.compile(regxStr); 153 Matcher isNo=pattern1.matcher(str); 154 if(isNo.matches()){ 155 flag=true; 156 } 157 return flag; 158 } 159 160 }
这就不多解释了,直接使用
1 if (!IDCardUtils.isIDCard(id)){ 2 showCustomToast("身份证格式不正确"); 3 return; 4 }
哈哈,这就OK了,大家可以试试啊!感觉特别棒