V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
shaobo76
V2EX  ›  Python

[求教] 如何在一串字符中识别出身份证号码

  •  
  •   shaobo76 · 2017-05-11 18:17:21 +08:00 · 7164 次点击
    这是一个创建于 2755 天前的主题,其中的信息可能已经有所发展或是发生改变。

    情况是有多条记录,每条记录由一串数字构成,在不确定的位置上出现身份证号码,身份证号只会出现一次且没有其他类似身份证号的数字串。如何通过编程的方法自动识别出身份证号的位置,用 r 或者 python 实现的话要用到什么包,请各位大侠指点,多谢。

    24 条回复    2017-05-12 15:15:35 +08:00
    okKO
        1
    okKO  
       2017-05-11 18:19:50 +08:00 via Android
    正则表达式处理这个没难度吧~
    grimpil
        2
    grimpil  
       2017-05-11 18:20:13 +08:00
    正则表达式吧
    shaobo76
        3
    shaobo76  
    OP
       2017-05-11 18:26:28 +08:00
    @okKO
    @grimpil
    正则表达式不太熟,能不能再提示一下
    zjqzxc
        4
    zjqzxc  
       2017-05-11 18:27:15 +08:00
    正则匹配 18/17 位(必要时候还需要考虑 15 位)数字

    如果不放心是否会出现干扰字符串的话,取出来的结果检验一下最后一位的校验位
    shaobo76
        5
    shaobo76  
    OP
       2017-05-11 18:34:48 +08:00 via Android
    @zjqzxc 假设这个数字串有 100 个数字构成,怎么匹配 18 位数字呢,那不是会命中很多个?
    oh
        6
    oh  
       2017-05-11 18:37:33 +08:00   ❤️ 6
    根据身份证号码的含义,第 7-14 是生日,那基本可以确定:
    - 第 7 位要么是 1 要么是 2 ( 1xxx 年 - 2xxx 年);
    - 第 11 位要么是 0 要么是 1 ( 0x 月 - 1x 月);
    - 第 13 位的范围是 0 - 3 ( 0x 日 - 3x 日);
    - 第 18 位除了是数字还有可能是 X ;

    有了这几个限定位,很大程度上可以避免干扰了(当然要根据具体的内容而定,如果是几百几千个数字里面去找出 18 位身份证,那就不成立了)。

    正则大概可以写为: \d{6}[1-2]\d{3}[0-1]\d[0-3]\d{4}[0-9xX]

    简单测试了一下,可能考虑不周。
    oh
        7
    oh  
       2017-05-11 18:39:24 +08:00
    @shaobo76

    如果是在 100 个数字串里面去找 18 位身份证号码,那根据上面提取之后,最好是用身份证号码校验公式校验一次(身份证第 18 位是校验符,以此检测身份证号码的合法性),网上搜一下就有计算公式。
    kaneg
        8
    kaneg  
       2017-05-11 18:40:52 +08:00 via iPhone
    先用正则缩小范围,比如在 n 个字符串里找到 m 个候选项,然后再用程序严格的分析,比如最后的检验位是否匹配
    ynyounuo
        9
    ynyounuo  
       2017-05-11 18:45:15 +08:00
    @shaobo76
    /([1-8][0-9])\d{4}(19|20)\d{6,9}[\dXx]/
    maxmilia
        10
    maxmilia  
       2017-05-11 18:51:07 +08:00
    匹配 18 个数字,按验证的算法算算验证位合法不,哈哈哈哈哈
    maxmilia
        11
    maxmilia  
       2017-05-11 18:52:10 +08:00
    哦 不对 还有 x
    ynyounuo
        12
    ynyounuo  
       2017-05-11 18:52:10 +08:00   ❤️ 1
    @ynyounuo 根据 #6 改了一下
    /([1-8][0-9])\d{4}(19|20)(\d{2})(0?[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])(\d{3})[\dXx]/
    shaobo76
        13
    shaobo76  
    OP
       2017-05-11 19:07:27 +08:00 via Android
    谢谢大家,我去尝试一下(•̀⌄•́)
    zhihaofans
        14
    zhihaofans  
       2017-05-11 20:03:24 +08:00   ❤️ 2
    tool.oschina.net 找到正则测试,右边有身份证的例子
    dream7758522
        15
    dream7758522  
       2017-05-11 20:11:06 +08:00 via Android
    很简单,不过我这方法可能效率不高。首先读前 18 个字符串,判断是否是身份证,然后从字符串第二位开始读 18 位字符串,判断。如此循环。文件不是很大的话,应该很简单方便。写正则的话可能还要多次验证正则表达式写的是否正确,很花时间的,与其浪费自己的时间,还不如浪费电脑的时间。
    mingyun
        16
    mingyun  
       2017-05-12 00:02:09 +08:00
    @oh nice
    geelaw
        17
    geelaw  
       2017-05-12 00:59:03 +08:00
    首先前 6 位和出生地 /户籍有关,只有有限种可能,找到这个表;
    然后是 8 位或 6 位生日,可以用求余数的方法判断年份是否是闰年,然后判断月、日的组合是否 valid ;
    然后是 3 位任意的数;
    最后是校验位,这位也可以通过前面的算出来,而且很容易(因为是前面几位线性组合求余数)。

    于是你可以画一个 NFA,然后再把它转换为正则表达式。
    JerryV2
        18
    JerryV2  
       2017-05-12 09:12:10 +08:00
    @dream7758522 正则是值得花时间练习的,不是浪费时间啊兄弟
    AyoCross
        19
    AyoCross  
       2017-05-12 09:19:34 +08:00
    +1,正则这东西需要经常练练手,否则时间长了规则就忘了
    springz
        20
    springz  
       2017-05-12 10:58:05 +08:00
    身份证号有特殊规则,正则取出符合格式的字符串,再走一遍效验就可以了
    billgreen1
        22
    billgreen1  
       2017-05-12 11:50:11 +08:00
    @geelaw 我和你想的一样,现在很多正则表达式,把一些不是身份证的也给匹配出来了
    killerv
        23
    killerv  
       2017-05-12 12:26:14 +08:00
    根据身份证号码的规则写个正则,应该没问题
    as463419014
        24
    as463419014  
       2017-05-12 15:15:35 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1049 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 20:34 · PVG 04:34 · LAX 12:34 · JFK 15:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.