跟我学正则之——用正则校验身份证号码

一个阳光的周末,一个充实的周末,不知不觉从中午12点写代码写到晚上12点,除了中间吃饭之外,我一直坐在电脑旁边,时间过得很快,很久很久之前,我的周末与晚上也是这样度过的,又让我想起从前的日子。呵呵,闲话少说,来点实的。

要做身份证校验,首先我们要了解它的规则,否则就谈不上校验了,身份证分第一代和第二代,分别是15位及18位,规则如下:

* 1.15位的身份证号码

*  a.必需全部是数字

*  b.第九十位是月份,只能是01至12

*  c.第十、十一位是天,只能是01至31

* 2.18位的身份号码

*  1.除最后一位可以是X外,必需全部是数字

*  2.第七至十位是年份,第9-10位只能是19或20,超过2099年的身份证做错误处理,估计我写的这个代码,到2099年也没啥用了

*  3.第十、十一位是月份,同15位身份证

*  4.第十二、十三位是天,同15位身份证

先来看15位的,前面8位是任意数字,用d{8},d表示数字,d{8}表示必需匹配8个数字。

接下下是月份,月份为01至12需要分解,当月分的第一个数字是0的时候,第二个数可以匹配1-9,为什么0不匹配呢,因为不可能有00月。当月份的第一个数字是1时候,第二位数可以匹配0-2,也就是10、11、12三个月。这个正则是:((0[1-9])|(1[012])),表示匹配第一个数字取0时候,第二数字取1-9;或者第一个数字取1的时候,第二个数字取0、1、2。这里的|是或的意思,括号表示一个匹配块,和做boolean运算的时候括号一样。

接下来要匹配天,天可以是01-31,也要分解成三种情况,当第一个数字是0的时候,第二个数字可以是1-9;当第一个数字是1和2的时候,第二个数字可以是0-9;当第一个数字是3的时候,第二个数字可以是0和1,那么我们可以出正则如下:0[1-9]|[12][0-9]|3[01]。

第十三至十五位,必需是数字,这个正则就很简单了,d{3},匹配3个数字。

完整的正则如下:"^d{8}((0[1-9])|(1[012]))(0[1-9]|[12][0-9]|3[01])d{3}$"

再来看18位的身份证,前面6位是任意数字,就是d{6}了。第七至第十位,是年份的数字,这里我们只取19xx至20xx年,超过这个时间不考虑。正则如下:(19)|(20)d{2}。月份和天同15是一样的。最后一位可能是X,正则是:[0-9]|X$。18位身份证完整的正则:"^d{6}(19)|(20)d{2}((0[1-9])|(1[012]))(0[1-9]|[12][0-9]|3[01])d{3}[0-9]|X$"

心细的读者可能会发现,日期实际上存在着闰年情况,而且2月份不是31天,我们需要对日期进行校验。完整的代码如下

         ///
         /// 判断是否为身份证
         ///
         ///

         ///
         public static bool IsIdCard(string input)
         {
             /*
              * 1.15位的身份证号码
              *  a.必需全部是数字
              *  b.第九十位是月份,只能是01至12
              *  c.第十、十一位是日期,只能是01至31
              * 2.18位的身份号码
              *  1.除最后一位可以是X外,必需全部是数字
              *  2.第七至十位是年份,第9-10位只能是19或20,超过2099年的身份证做错误处理,估计我写的这个代码,到2099年也没啥用了
              *  3.第十、十一位是月份,同15位身份证
              *  4.第十二、十三位是日期,同15位身份证
              */
             string pattern15 = @"^d{8}((0[1-9])|(1[012]))(0[1-9]|[12][0-9]|3[01])d{3}$";
             string pattern18 = @"^d{6}(19)|(20)d{2}((0[1-9])|(1[012]))(0[1-9]|[12][0-9]|3[01])d{3}[0-9]|X$";
             bool result = Regex.IsMatch(input, pattern15) || Regex.IsMatch(input, pattern18, RegexOptions.IgnoreCase);
             if (result)
             {
                 //检查日期
                 string dateStr = string.Empty;
                 int step;
                 if (input.Length == 15)
                 {
                     step = 0;
                     dateStr = "19";
                 }
                 else
                 {
                     step = 2;
                 } 

                 dateStr += input.Substring(6, 6 + step);
                 DateTime date;
                 return DateTime.TryParse(input, out date);
             } 

             return result;
         }

因为我写代码的时候是写了几个函数的,这里作了一个整合,没有进行测试,有可能存在问题。

  

注意:本文为我的独立博客镜像博客,自发表不再更新,原文可能随时被更新,敬请访问原文。同时,请大家不要在此评论,如果有什么看法,请点击这里:http://iove.net/1705/

本文来自http://iove.net,欢迎转载,转载敬请保留相关链接,否则视为侵权,原文链接:http://iove.net/1705/

转载于:https://www.cnblogs.com/conis/archive/2009/03/29/1720511.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值