在开发中,我们需要验证用户的输入信息,多半采用正则验证,下面就是身份证证号的几种常用的正则表达式:
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,
];
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/
来自:https://www.cnblogs.com/starryqian/archive/2019/01/15/10272793.html
这次,我们将学习如何编写更优雅的模式并定义搜索字符串的位置。我们知道星号 * 可以使表达式匹配 0 次或多次。这相当于{0,}。实际上还有其他更短的形式,使用它们可以使样式更优雅,更短。
本文给出了两个密码强度的正则表达式方案,一个简单,一个更复杂和安全。并分别给出了两个方案的解析和测试程序。一般大家可以根据自己的项目的实际需要,自行定义自己的密码正则约定。
一般表单页面都需要填写手机号,校验用户输入的手机号码是否正确,就要用到正则表达式,用正则表达式来匹配手机号段,如在运营商号段内,则号码正确。因此,需要知道运营商最新的号段,如下所示:
参数为字符串, 那么第二个参数表示正则表达式的修饰符,如下:字符串对象共有4个方法,可以使用正则表达式: match()、 replace()、search() 和 split()。
正则表达式或regex用于匹配字符串的各个部分 下面是我创建正则表达式的备忘单。匹配正则使用 .test() 方法,匹配多个模式使用操作符号 |,使用i标志表示忽略大小写
正则表达式(regex)是定义搜索模式的字符序列。由于对程序员的日常工作非常有用,所以在 JavaScript 中也支持它。在这个系列文章中,我会向你展示其工作方式以及其实际用途
正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。搜索模式可用于文本搜索和文本替换。
JS中判断一个字符串是否包含汉字,下面就介绍2中常用的实现方法:用正则表达式判断、用 Unicode 字符范围判断。
正则表达式,一个十分古老而又强大的文本处理工具,仅仅用一段非常简短的表达式语句,便能够快速实现一个非常复杂的业务逻辑。熟练地掌握正则表达式的话,能够使你的开发效率得到极大的提升。
统一代码为18位,统一代码由十八位的数字或大写英文字母(不适用I、O、Z、S、V)组成,由五个部分组成:第一部分(第1位)为登记管理部门代码,9表示工商部门;(数字或大写英文字母)
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!