python正则抓取身份证号码
ID_c=r'(?<!\d)(?:(?:([1-9]\d{5}(?:18|19|(?:[23]\d))\d{2}(?:(?:0[1-9])|(?:10|11|12))(?:(?:[0-2][1-9])|10|20|30|31)\d{3}[0-9Xx])(?!\d))|([1-9]\d{5}\d{2}(?:(?:0[1-9])|(?:10|11|12))(?:(?:[0-2][1-9])|10|20|30|31)\d{3}))(?!\d)'
ID = re.findall(ID_c,text)
ID = list(map(lambda x:''.join(x) ,ID))
简要分析:
18位身份证号匹配:
(?:(?:([1-9]\d{5}(?:18|19|(?:[23]\d))\d{2}(?:(?:0[1-9])|(?:10|11|12))(?:(?:[0-2][1-9])|10|20|30|31)\d{3}[0-9Xx])(?!\d))
15位身份证号匹配:
([1-9]\d{5}\d{2}(?:(?:0[1-9])|(?:10|11|12))(?:(?:[0-2][1-9])|10|20|30|31)\d{3})
简单的排除一些错误的匹配:
1,身份证号前面的字符不为数字:
(?<!\d)
2,身份证号后面的字符不为数字:
(?!\d)
验证身份证号码是否正确
代码验证18位号码是否正确
# t代表身份证号码的位数,w表示每一位的加权因子
t = []
w = []
for i in range(0,18):
t1 = i + 1
t.append(t1)
w1 = (2 ** (t1-1)) % 11
w.append(w1)
#队列w要做一个反序
w = w[::-1]
#根据前17位的余数,计算第18位校验位的值
def for_check(n):
# t = 0
for i in range(0,12):
if (n + i) % 11 == 1:
t = i % 11
if t == 10:
t = 'X'
return t
#根据身份证的前17位,求和取余,返回余数
def for_mod(id):
sum = 0
for i in range(0,17):
sum += int(id[i]) * int(w[i])
# print(int(id[i]),int(w[i]),sum)
sum = sum % 11
# print(sum)
return sum
#验证18位身份证有效性
def check_true(id):
# print(for_check(for_mod(id[:-1])))
if id[-1] == 'X':
if for_check(for_mod(id[:-1])) == 'X':
return True
else:
return False
else:
if for_check(for_mod(id[:-1])) == int(id[-1]):
return True
else:
return False
提取18位身份证号码并验证:
id_15=[]
id_18=[]
for i in ID:
if len(i)==18:
id_18.append(i)
continue
if len(i)==15:
id_15.append(i)
continue
else:
#打印长度非18和15位的身份证号码
print(i)
# id_=data['身份证号码']
for i in id_18:
if check_true(str(i))==False:
# 打印验证错误的身份证号
print(i)
验证工具
以上代码只是验证了规则的正确性,但是对于地址位是否是有实际意义没有验证
Python大陆居民身份证、港澳台居民居住证验证工具 :https://github.com/jxlwqq/id-validator.py
jupyter 嵌入网页验证工具
只是为了方便验证一下
from IPython.display import IFrame
IFrame('http://welefen.com/lab/id/index.php', width=800, height=300)