要使用正则表达式判断一个字符串是否为合法身份证号,可以按照以下步骤进行操作。
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技术站