业务过程中,遇到了身份证判断是否有效的问题。如能连接公安系统进行身份证判断,自然是最准确的,但是这对普通码农来讲是不现实的。
现根据大陆身份证号码规律,自己写判断规则,利用正则表达式来判断给定的字符串是否是近似一个有效的身份证号码。并将代码封装为一个Mysql函数,方便代码复用。
注意:本代码所用规则根据一代、二代身份证的数字规律进行建立,只能近似保证号码判断的准确性、排除大多数录入数据不规则的的情况,但针对少数符合规则但属于无效的情况,这里无法判断。
废话少说,直接上码:
DELIMITER $$
USE `analysis`$$
DROP FUNCTION IF EXISTS `is_ID_card`$$
CREATE DEFINER=`lws`@`%` FUNCTION `is_ID_card`(number VARCHAR(20)CHARSET utf8) RETURNS TINYINT(1)
BEGIN
DECLARE flag BOOL DEFAULT FALSE;
IF (LENGTH(number)=18
AND number REGEXP CONCAT('^(([1][1-5])|([2][1-3])|([3][1-7])|([4][1-6])|([1][0-4])|([6][1-6])|([7][1])|([8][1-2]))', -- 1、2位
'(([0][0-9])|([1][0-9])|([2][0-9])|([3][0-9])|([4][0-3])|([5][1-3])|([8][2])|([9][0]|[1]|[9]))', -- 3、4位
'(([0-3][0-9])|([4][0-4])|([5][1])|([8][1-9])|([9][0-9]))', -- 5、6位
'(([1]([8]|[9])[0-9])|([2]([0]|[0-1])[0-9]))[0-9](0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])[0-9]{3}([0-9]|X)') -- 后12位
OR (LENGTH(number)=15
AND number REGEXP CONCAT('^(([1][1-5])|([2][1-3])|([3][1-7])|([4][1-6])|([1][0-4])|([6][1-6])|([7][1])|([8][1-2]))',
'(([0][0-9])|([1][0-9])|([2][0-9])|([3][0-9])|([4][0-3])|([5][1-3])|([8][2])|([9][0]|[1]|[9]))',
'(([0-3][0-9])|([4][0-4])|([5][1])|([8][1-9])|([9][0-9]))',
'(0[1-9]|[1-9][0-9])(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1])[0-9]{3}')))
THEN SET flag = TRUE;
END IF;
RETURN flag;
END$$
DELIMITER ;
大家把上述代码保存为一个mysql函数,然后调用该函数即可。
使用方法:
SELECT is_ID_card('这里输入需要验证的身份证号码')
这里分18位身份证号码、15位身份证号码两种情况:
- 它们前六位一致,都是省级代码(前两位)、地市级代码(前4位)、县区级代码(前6位);
- 出生年月日方面,18位身份证是形如1990XXXX的格式,而15位身份证是形如79XXXX的格式,也即后者省去了年份的前两位;
- 18位身份证最后一位是校验码,可为数字或者X,而15位身份证没有最后一位校验码。
值的注意的是,代码中的正则表达式字符串由于过长,这里使用了一个小窍门来进行换行显示,以提高代码可读性:
先把原来的一个长正则表达式拆分为几个,再使用concat()函数连接起来,因为concat()函数内部参数之间是可以任意换行的,所以就变相实现了原字符串的换行。这一点,在以后遇到字符串需要换行的时候可以使用。
* 原创文章,如需转载请注明出处,谢谢合作!
扫描二维码关注公众号,回复:
2141095 查看本文章