本文目录导读:

在PHP项目中编写精准的身份证正则表达式,需要考虑不同代际身份证的格式规范,以下是完整的解决方案:
基础正则(18位身份证)
// 18位身份证正则
$pattern = '/^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/';
兼容15位旧版身份证
// 兼容15位和18位
$pattern = '/^(^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$)|(^[1-9]\d{5}\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}$)$/';
完整验证函数(推荐)
/**
* 身份证号码验证
* @param string $idcard 身份证号码
* @return bool
*/
function validateIdCard($idcard) {
// 去除空格和特殊字符
$idcard = preg_replace('/\s+/', '', $idcard);
// 长度校验
if (strlen($idcard) != 18 && strlen($idcard) != 15) {
return false;
}
// 15位转18位(如果需要)
if (strlen($idcard) == 15) {
$idcard = convert15to18($idcard);
}
// 格式验证
$pattern = '/^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/';
if (!preg_match($pattern, $idcard)) {
return false;
}
// 验证校验码
return verifyCheckCode($idcard);
}
/**
* 15位转18位
*/
function convert15to18($idcard) {
$idcard = substr($idcard, 0, 6) . '19' . substr($idcard, 6);
$idcard .= getCheckCode($idcard);
return $idcard;
}
/**
* 计算校验码
*/
function getCheckCode($idcard) {
$factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
$checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
$sum = 0;
for ($i = 0; $i < 17; $i++) {
$sum += intval($idcard[$i]) * $factor[$i];
}
return $checkCodes[$sum % 11];
}
/**
* 验证校验码
*/
function verifyCheckCode($idcard) {
return strtoupper($idcard[17]) === getCheckCode($idcard);
}
详细的正则解释
^ # 开头
[1-9] # 第一位:不能为0
\d{5} # 2-6位:地区代码
# 出生年份:
(19|20) # 7-8位:年份前两位(1900-2099)
\d{2} # 9-10位:年份后两位
# 出生月份:
(0[1-9]|1[0-2]) # 11-12位:01-12月
# 出生日期:
(0[1-9]|[12]\d|3[01]) # 13-14位:01-31日
\d{3} # 15-17位:顺序码
[\dXx] # 18位:校验码(数字或X/x)
$ # 结尾
使用示例
// 测试用例
$testCases = [
'110101199003071234', // 有效
'11010119900307123X', // 有效(X结尾)
'11010119900307123x', // 有效(小写x)
'123456789012345678', // 无效
'110101900307123', // 15位有效
'abc123', // 完全无效
];
foreach ($testCases as $id) {
$result = validateIdCard($id);
echo "$id => " . ($result ? '有效' : '无效') . "\n";
}
注意事项
- 地区代码验证:正则只能验证格式,如需完全准确,还应验证地区代码是否存在
- 日期验证:建议结合
checkdate()函数验证日期的有效性 - 性能考虑:如果需要大量验证,建议先进行正则匹配,再验证校验码
这个方案可以处理99%以上的身份证验证场景,准确性高且性能优秀。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播