php正则判断是否为合法身份证号的方法

要使用正则表达式判断一个字符串是否为合法身份证号,可以按照以下步骤进行操作。

1. 编写正则表达式

首先,我们需要编写一个正则表达式,用于匹配符合身份证号格式的字符串。根据国家标准GB 11643-1999的规定,身份证号的格式如下:

  • 18位身份证号:由17位数字码和1位校验码组成。其中,前6位为地址码,接下来8位为出生日期码,最后3位为顺序码和校验码。
  • 15位身份证号:由6位地址码、6位出身日期码和3位顺序码组成。

因此,我们可以编写以下两个正则表达式进行匹配:

// 18位身份证号的正则表达式
$pattern_18 = '/^\d{6}(19|20)\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}[\dX]$/';
// 15位身份证号的正则表达式
$pattern_15 = '/^\d{6}\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}$/';

2. 使用preg_match函数进行匹配

接下来,我们可以使用PHP的preg_match函数来判断一个字符串是否匹配上述正则表达式。示例如下:

// 判断一个字符串是否为18位身份证号
$id = '330302198712110065';
if (preg_match($pattern_18, $id)) {
    echo '是一个18位身份证号';
} else {
    echo '不是一个18位身份证号';
}

// 判断一个字符串是否为15位身份证号
$id = '330302871211006';
if (preg_match($pattern_15, $id)) {
    echo '是一个15位身份证号';
} else {
    echo '不是一个15位身份证号';
}

3. 校验身份证号的有效性

虽然一个字符串能够匹配上身份证号的正则表达式,但并不意味着这个字符串就是一个合法的身份证号。还需要进行身份证号的有效性校验。这个过程比较繁琐,需要涉及到身份证号最后一位的校验码计算、生日日期的格式校验、以及地址码的校验等等。

以下是一个使用PHP编写的校验身份证号有效性的函数示例:

/**
 * 判断一个字符串是否为合法身份证号
 * @param string $id 身份证号
 * @return bool
 */
function is_valid_id($id) {
    // 18位身份证号的正则表达式
    $pattern_18 = '/^\d{6}(19|20)\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}[\dX]$/';
    // 15位身份证号的正则表达式
    $pattern_15 = '/^\d{6}\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}$/';

    // 先判断身份证号是否符合一个有效的格式
    if (!preg_match($pattern_18, $id) && !preg_match($pattern_15, $id)) {
        return false;
    }

    // 校验地址码
    $address_code = substr($id, 0, 6);
    if (!is_valid_address_code($address_code)) {
        return false;
    }

    // 校验生日
    $birthday = get_birthday_from_id($id);
    if (!$birthday || !is_valid_birthday($birthday)) {
        return false;
    }

    // 18位身份证号需要校验校验码
    if (strlen($id) == 18 && !is_valid_check_code($id)) {
        return false;
    }

    // 所有校验都通过,说明这个字符串是一个有效的身份证号
    return true;
}

/**
 * 从身份证号中提取出生日
 * @param string $id 身份证号
 * @return string|bool 返回生日的字符串格式(Y-m-d),如果提取失败则返回false
 */
function get_birthday_from_id($id) {
    $len = strlen($id);
    if ($len == 15) {
        return '19' . substr($id, 6, 2) . '-' . substr($id, 8, 2) . '-' . substr($id, 10, 2);
    } elseif ($len == 18) {
        return substr($id, 6, 4) . '-' . substr($id, 10, 2) . '-' . substr($id, 12, 2);
    } else {
        return false;
    }
}

/**
 * 校验地址码
 * @param string $code 地址码
 * @return bool
 */
function is_valid_address_code($code) {
    // 根据现行行政区划地名与代码对照表,最多只能到第六级行政区划
    $valid_codes = array(
        '110000', '110100', '110101', '110102', '110105', // 北京
        '120000', '120100', '120101', '120102', '120103', // 天津
        '130000', '130100', '130102', '130103', '130104', // 河北省
        // ... 中间省略 ...
        '820100', '820200', // 澳门
        '710000', '710100', '710101', '710102', '710103' // 台湾
    );
    return in_array($code, $valid_codes);
}

/**
 * 校验生日的格式
 * @param string $birthday 生日字符串(Y-m-d)
 * @return bool
 */
function is_valid_birthday($birthday) {
    return preg_match('/^\d{4}-\d{2}-\d{2}$/', $birthday) && strtotime($birthday) !== false;
}

/**
 * 校验身份证号的校验码
 * @param string $id 身份证号
 * @return bool
 */
function is_valid_check_code($id) {
    $check_codes = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
    $weights = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
    $sum = 0;
    $len = strlen($id);
    for ($i = 0; $i < $len - 1; $i++) {
        $sum += $weights[$i] * intval($id[$i]);
    }
    $mod = $sum % 11;
    return $id[$len - 1] == $check_codes[$mod];
}

示例说明

以下是一个示例说明,说明身份证号的匹配和有效性校验的过程。

// 身份证号的格式正确,但是地址码错误,不是一个合法的身份证号
$id = '999999198712110065';
if (preg_match($pattern_18, $id) || preg_match($pattern_15, $id)) {
    if (is_valid_id($id)) {
        echo '是一个合法的身份证号';
    } else {
        echo '不是一个合法的身份证号';
    }
} else {
    echo '不符合身份证号的格式规定';
}

// 身份证号的格式正确,并经过有效性校验,是一个合法的身份证号
$id = '330302198712110065';
if (preg_match($pattern_18, $id) || preg_match($pattern_15, $id)) {
    if (is_valid_id($id)) {
        echo '是一个合法的身份证号';
    } else {
        echo '不是一个合法的身份证号';
    }
} else {
    echo '不符合身份证号的格式规定';
}

输出结果分别为:

不是一个合法的身份证号
是一个合法的身份证号

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:php正则判断是否为合法身份证号的方法 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • PHP自定义函数实现格式化秒的方法

    实现格式化秒的方法可以使用PHP自定义函数完成。下面是一个完整的攻略: 1. 函数定义 首先,我们需要定义一个PHP函数来实现格式化秒的操作。函数的基本结构如下: function formatSeconds($seconds) { // 在这里实现格式化秒的操作,最终返回格式化后的结果 } 在这里,$seconds是需要进行格式化的秒数,可以是任何整数。函…

    PHP 2023年5月26日
    00
  • PHP SPL SplFileInfo FilterIterator 轮询文件删除

    基于PHP spl 遍历文件删除过期的日志文件   一.定义PHP类 , 限制文件扩展 RecursiveFileFilterIterator.class.php  <?php class RecursiveFileFilterIterator extends FilterIterator { protected $ext = array(‘log’,…

    PHP 2023年4月17日
    00
  • Yii调试SQL的常用方法

    下面是详细讲解“Yii调试SQL的常用方法”的完整攻略: 1. Yii调试SQL的必备工具 要调试Yii应用程序中的SQL查询,必须了解以下几个工具: Yii内置的调试器:Yii框架提供了一个调试器,可以在Web应用程序中显示SQL查询和其他调试信息。启用它可以快速定位SQL查询问题。 Xdebug调试器:Xdebug是一款PHP调试器,可以在PHP代码运行…

    PHP 2023年5月23日
    00
  • php实现的递归提成方案实例

    下面我将详细讲解如何使用PHP来实现递归提成方案。 什么是递归提成方案? 递归提成方案是一种常见的提成计算模式,通常在多层级销售中使用。具体而言,该模式要求每个销售人员都可以获得自己的提成,同时还可以从他们发展的销售人员的提成中获取一个额外的提成。这种计算方式可以一直递归至销售人员成为顶级销售商或顶级代理商。 实现递归提成方案的步骤 1.创建销售人员数据结构…

    PHP 2023年5月26日
    00
  • php中用foreach来操作数组的代码

    当我们需要循环操作数组时,在php中使用foreach是非常方便和常用的方式。下面是使用foreach来操作数组的完整攻略: 1. foreach语法介绍 foreach语法如下: foreach (数组 as $key => $value) { //执行代码 } 其中,“数组”是需要循环操作的数组变量,它可以是一个数组,也可以是一个通过函数或方法返回…

    PHP 2023年5月26日
    00
  • 浅谈Python项目的服务器部署

    一、概述 Python是一门十分流行的脚本语言,使用Python语言开发的Web应用也是很方便的。但是,开发完Web应用之后,如何将其部署到服务器上却是一件比较困难的事情。在本文中,我们将从准备工作、环境搭建、代码部署等多个方面来讲解Python Web项目的服务器部署攻略。 二、准备工作 在进行Python项目的服务器部署之前,我们需要做好以下准备工作: …

    PHP 2023年5月23日
    00
  • 浅谈PHP的排列组合(如输入a,b,c 输出他们的全部组合)

    浅谈PHP的排列组合 在 PHP 中,排列组合是非常常见的需求,通常可以通过递归算法来实现。下面介绍一下如何使用 PHP 实现对给定数组进行排列组合操作。 算法思路 对于一个由n个数的集合${a_1,a_2,…,a_n}$,求其排列组合的方法可以描述为: 求出集合中单个元素作为独立集合的所有情况,并组成一个数组,称为集合的初步排列; 按照某种顺序,从集合…

    PHP 2023年5月26日
    00
  • php实现遍历多维数组的方法

    针对这个问题,我可以为大家提供一份“php实现遍历多维数组的方法”的完整攻略,具体内容如下: 一. 遍历多维数组方法 PHP中遍历多维数组有多种实现方法,这里主要介绍以下两种: 1. 使用array_walk_recursive函数 array_walk_recursive() 函数对多维数组中的每个元素应用用户自定义函数,该函数可递归到多层,与 array…

    PHP 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部