在开发中,我们需要验证用户的输入信息,多半采用正则验证,下面就是身份证证号的几种常用的正则表达式:

var  reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;

var reg= /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/;

var  reg = /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/;

但是这些并不能管用,是不是很气人?

这是为什么呢?

下面我们看一下身份证的规则

身份证查询系统说明:

输入准确的18位身份证号码即可查询身份证号码归属地,年龄,性别,通过身份证号码查询姓名。

输入不合法格式的身份证号码会提示身份证号码错误,本身份证号码查询系统也可作为身份证号码验证。

身份证号码和姓名格式科普:前1-6位为行政区划代码即归属地,第7-14位为出生年月日,第15-17位为顺序代码,在同一个地区出生同一个出生的人通过顺序号码区分,第17位奇数表示男性,偶数表示女性,第18位为校验码,用于校验身份证号码是否合法

很显然我们正则验证出错的原因就是第18位,用于身份证号是否合法验证的校验

这是为什么呢?是不是很诡异?按照道理讲,不应该不符合就是false?但是返回的都是true;

因为是这样的,我们使用的正则表达式 reg.test(''),当我们使用test其实就是通过我们写的正则表达式去动态匹配我们输入的字符串是否符合我们表达式的要求,如果符合就会返回Boolean值

这就是为什么我们身份证验证会出错,因为我们正则只是匹配了形式,并没有按照身份证的规则去动态验证,没有权重

那么正确的验证如下

 /**
* @params idCard string
* @outParams res
* status : boolean
* msg : string
*
*/
function checkIdcard(idCard) {
idCard = idCard.toString();
var city = {
11: "北京",
12: "天津",
13: "河北",
14: "山西",
15: "内蒙古",
21: "辽宁",
22: "吉林",
23: "黑龙江 ",
31: "上海",
32: "江苏",
33: "浙江",
34: "安徽",
35: "福建",
36: "江西",
37: "山东",
41: "河南",
42: "湖北 ",
43: "湖南",
44: "广东",
45: "广西",
46: "海南",
50: "重庆",
51: "四川",
52: "贵州",
53: "云南",
54: "西藏 ",
61: "陕西",
62: "甘肃",
63: "青海",
64: "宁夏",
65: "新疆",
71: "台湾",
81: "香港",
82: "澳门",
91: "国外 "
};
var tip = "";
var pass = true; if (
!idCard ||
!/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(
idCard
)
) {
tip = "身份证号格式错误";
pass = false;
} else if (!city[idCard.substr(0, 2)]) {
tip = "地址编码错误";
pass = false;
} else {
//18位身份证需要验证最后一位校验位
if (idCard.length == 18) {
idCard = idCard.split("");
//∑(ai×Wi)(mod 11)
//加权因子
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
//校验位
var parity = [1, 0, "X", 9, 8, 7, 6, 5, 4, 3, 2];
var sum = 0;
var ai = 0;
var wi = 0;
for (var i = 0; i < 17; i++) {
ai = idCard[i];
wi = factor[i];
sum += ai * wi;
}
var last = parity[sum % 11];
if (parity[sum % 11] != idCard[17]) {
tip = "校验位错误";
pass = false;
}
}
}
var obj = {
status: pass,
msg: tip
};
if (!pass) {
return obj;
} return obj;
}

写法注意事项:省区编码,我们可以写成数组的形式,但是需要去循环操作,会比较消耗性能:如果是数组,新手是这么写的

function checkIdcard(idCard) {
idCard = idCard.toString();
var city = [
11,
12,
13,
14,
15,
21,
22,
23,
31,
33,
34,
35,
36,
37,
41,
42,
43,
44,
45,
46,
50,
51,
52,
54,
61,
62,
63,
64,
65,
71,
81,
91
];
var tip = "";
var pass = true;
var Flag = true;
for(var i=0;i<city.length;i++){
if (city[i] == idCard.substr(0, 2)) Falg= false;
}
if (
!idCard ||
!/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(
idCard
)
) {
tip = "身份证号格式错误";
pass = false;
} else if (!Flag) {
tip = "地址编码错误";
pass = false;
} else {
//18位身份证需要验证最后一位校验位
if (idCard.length == 18) {
idCard = idCard.split("");
//∑(ai×Wi)(mod 11)
//加权因子
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
//校验位
var parity = [1, 0, "X", 9, 8, 7, 6, 5, 4, 3, 2];
var sum = 0;
var ai = 0;
var wi = 0;
for (var i = 0; i < 17; i++) {
ai = idCard[i];
wi = factor[i];
sum += ai * wi;
}
var last = parity[sum % 11];
if (parity[sum % 11] != idCard[17]) {
tip = "校验位错误";
pass = false;
}
}
}
var obj = {
status: pass,
msg: tip
};
if (!pass) {
return obj;
} return obj;
}

  优化上面的代码

/**
* @params idCard string
* @outParams res
* status : boolean
* msg : string
*
*/
function checkIdcard(idCard) {
idCard = idCard.toString();
var city = [
11,
12,
13,
14,
15,
21,
22,
23,
31,
33,
34,
35,
36,
37,
41,
42,
43,
44,
45,
46,
50,
51,
52,
54,
61,
62,
63,
64,
65,
71,
81,
91
];
var tip = "";
var pass = true; if (
!idCard ||
!/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(
idCard
)
) {
tip = "身份证号格式错误";
pass = false;
} else if (city.indexOf(idCard.substr(0, 2)) < 0) {
tip = "地址编码错误";
pass = false;
} else {
//18位身份证需要验证最后一位校验位
if (idCard.length == 18) {
idCard = idCard.split("");
//∑(ai×Wi)(mod 11)
//加权因子
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
//校验位
var parity = [1, 0, "X", 9, 8, 7, 6, 5, 4, 3, 2];
var sum = 0;
var ai = 0;
var wi = 0;
for (var i = 0; i < 17; i++) {
ai = idCard[i];
wi = factor[i];
sum += ai * wi;
}
var last = parity[sum % 11];
if (parity[sum % 11] != idCard[17]) {
tip = "校验位错误";
pass = false;
}
}
}
var obj = {
status: pass,
msg: tip
};
if (!pass) {
return obj;
} return obj;
}

注意一下写法,尽量减少循环的操作,推荐使用第一种和第三种用法;如果你是es6用户,那么建议var 修改成 let

最后基于模块的思想,建议搭建可以在实际开发中,把验证的方法统一一个对象去处理,

然后哪里需要哪里引入。

参考博文:https://blog.csdn.net/a632202838/article/details/44827427

在线身份查询:http://sfz.diqibu.com/

正则匹配身份证有bug你知道么?的更多相关文章

  1. js正则匹配身份证号 有坑

    // 不能加g,每次匹配会以lastIndex为起始位去查找 // 若加g,匹配到会用最后一位的index去改变lastIndex,没有匹配到则会把lastIndex重置为0 // 不加g,lastI ...

  2. 详解一个自己原创的正则匹配IP的表达式

    这里给大家详细讲解一下一个匹配IP地址的正则表达式, 有关正则方面的知识,会在详细的讲解中提到. 在讲解之前,我先给大家介绍一下,ip地址的生成规则. IP地址,是由32位数字二进制转为四个十进制的字 ...

  3. jQuery中的一些正则匹配表达式

    jQuery常用正则匹配表达式 落雨 //整数 "^-?[1-9]\\d*$", //正整数 "^[1-9]\\d*$", //负整数 intege2: &qu ...

  4. 常用的JavaScript正则匹配规则代码收藏,很实用

    收集一些常用的JavaScript正则表达式匹配规则,比如匹配电话号码.Email.中文字符.身份证号.邮编.QQ号.过滤空白行.匹配特定数字等.觉得这玩意是很有用的,只不过自己水平菜,老是自己写不出 ...

  5. 正则匹配<img src="xxxxxx" alt="" />标签的相关写法

    1.(<img\ssrc[^>]*>) 2.content.replace(/<img [^>]*src=['"]([^'"]+)[^>]*&g ...

  6. iOS 中的正则匹配(工具类方法)

    正则表达式 正则表达式是对字符串操作的一种逻辑公式, 用事先定义好的一些特定字符.及这些特定字符的组合, 组成一个"规则字符串", 这个"规则字符串"用来表达对 ...

  7. js 空正则匹配任意一个位置

    看一个正则 这里明显,起到匹配作用的是 | 后的,可 | 后什么都没有,原理不知道,也没有搜到文献,只有在 Reg101 上是这样解释的, 所以得出结论: js 中,空正则匹配任意一个位置. 不过,这 ...

  8. 通用且常用的Java正则匹配工具,用以检查邮箱名、电话号码、用户密码、邮政编码等合法性

    一个通用且常用的Java正则匹配工具,用以检查邮箱名.电话号码.用户密码.邮政编码等合法性. import java.util.regex.Matcher; import java.util.rege ...

  9. JS正则表达式一些基本使用、验证、匹配、正则匹配时一个变量

    js验证首位必须是字母 var str = "asfg"; /^[a-zA-Z].*/.test(str);//true是,false否 匹配所有空格 var str=" ...

随机推荐

  1. [Leetcode]931.下降路径最小和

    题目链接 这一题目首先需要弄懂题目的意思,下降路径最小和指的是在方阵中可以从上往下行走,走过后获得的值最小,方向可以是走左下,右下,直下. 题目和传统的动态规划一样,把边界的值先初始化,然后通过状态转 ...

  2. redis之事务

    一.是什么 可以一次执行多个命令,本质是一组命令集合.一个事务中的所有命令都会序列化,按顺序的串行化执行而不被其他命令插入,不许加塞.一个队列中,一次性.顺序性.排他性的执行一系列命令. 二.事务常用 ...

  3. .NET跨平台实践:再谈用C#开发Linux守护进程 — 完整篇

    Linux守护进程是Linux的后台服务进程,相当于Windows服务,对于为Linux开发服务程序的朋友来说,Linux守护进程相关技术是必不可少的,因为这个技术不仅仅是为了开发守护进程,还可以拓展 ...

  4. git commit --amend的撤销方法

    某同事执行git commit 时太兴奋,执行了 git commit --amend 慌了,不敢编辑上一个commit的description了,直接选择了wq退出,然而git毕竟强大,默认将改动合 ...

  5. qtcreator_process_stub中文输出乱码

    使用qt运行程序输出中文,全都变成了□,让人很头疼,百度了很久,找了一些解决方案都是: 用vim打开x11-common,在控制台输入 vim /etc/X11/Xresources/x11-comm ...

  6. Linux下升级Python到3.5.2版本

    原文出处:https://www.cnblogs.com/tssc/p/7762998.html 本文主要介绍在Linux(CentOS)下将Python的版本升级为3.5.2的方法 众所周知,在20 ...

  7. Kafka消费异常处理

    org.apache.kafka.clients.consumer.CommitFailedException: Commit cannot be completed since the group ...

  8. org.jeecgframework.core.common.exception.MyExceptionHandler]java.lang.NullPointerException

    问题原因:

  9. python使用requests请求的数据乱码

    1.首先进入目标网站,浏览器查看源码,找到head标签下面的meta标签,一般meta标签不止一个,我们只需找到charset属性里面的值即可 2.requests请求成功时,设置它的编码,代码如下 ...

  10. ELK常用命令

    1.查询当前所有的索引 #curl 'localhost:9200/_cat/indices?v' 2.查看集群健康状态 #curl 'localhost:9200/_cat/health?v' 绿色 ...