Python正则表达式实战:解析和验证香港身份证、车牌、电话格式
文章目录环境信息前言正则能匹配格式但匹配不了真假一、香港身份证号码的格式三层结构二、校验码算法mod 11 加权三、香港车牌格式传统 vs 自定义四、香港电话号码格式五、完整验证器可直接复用六、三个易错点坑1全角括号坑2字母转数字的偏移量坑3逻辑有效 ≠ 真实存在七、总结环境信息项目版本/说明Python3.10标准库re正则、无需第三方依赖验证对象香港身份证 / 车牌 / 电话号码数据来源格式规则和校验码算法为公开标准前言正则能匹配格式但匹配不了真假上周我在做一个表单数据清洗的活需要校验用户填写的香港身份证号码。我第一反应是写个正则表达式importre patternr^[A-Z]{1,2}\d{6}\([0-9A]\)$格式上是匹配了——1到2个大写字母 6位数字 括号里的校验码。但很快我就发现一个问题A123456(3)和A123456(9)都符合这个正则但只有一个是真的。正则表达式只能验证格式对不对验证不了号码是不是真实存在的。香港身份证号码里那个括号中的校验码不是随便写的——它是通过一个 mod 11 加权算法算出来的。格式匹配只是第一层校验码验证才是第二层。这篇文章讲的就是这两层验证。前半部分是正则解析香港身份证、车牌、电话的格式后半部分是香港身份证校验码算法的完整实现。收藏提示①正则匹配像不像校验码算法验证是不是真的。表单验证、数据清洗、反作弊缺一层都不行。文末有完整可复用的验证器代码。一、香港身份证号码的格式三层结构香港身份证号码由三部分组成以A123456(3)为例A 123456 (3) ↑ ↑ ↑ 字母 6位数字 校验码(0-9或A)规则开头是 1-2 个大写英文字母A-Z中间是 6 位数字括号里是校验码0-9 或字母 A括号可能是半角()或全角对应的正则importre# 支持半角/全角括号校验码0-9或AHKID_PATTERNre.compile(r^([A-Z]{1,2})(\d{6})[(]([0-9A])[)]$)defparse_hkid(hkid:str):解析香港身份证号码返回(字母部分, 数字部分, 校验码)mHKID_PATTERN.match(hkid.strip().upper())ifnotm:returnNonereturnm.group(1),m.group(2),m.group(3)# 测试print(parse_hkid(A123456(3)))# (A, 123456, 3)print(parse_hkid(AB9876543))# 全角括号也能识别print(parse_hkid(A1234563))# 无括号 → None不匹配注意一个细节我用了[(]和[)]来同时匹配半角和全角括号——香港用户在中文输入法下输入时经常打出全角括号只匹配半角会漏掉一大批真实数据。二、校验码算法mod 11 加权这是本文的核心。香港身份证的校验码算法是公开的逻辑如下字母转数字A10, B11, C12, …, Z35单字母补空格如果只有一个开头字母前面补一个空格值36加权相乘从右到左权重依次是 9,8,7,6,5,4,3,2,1校验码位权重是1求和取余所有乘积相加除以 11 取余数校验码规则余数 0 → 校验码是 0余数 1 → 校验码是 A余数 2~10 → 校验码 11 - 余数用A123456(3)举例验证A10单字母前面补空格36 加权36×9 10×8 1×7 2×6 3×5 4×4 5×3 6×2 324 80 7 12 15 16 15 12 481 481 ÷ 11 43 余 8 11 - 8 3 → 校验码 3 ✓完整实现defcalculate_hkid_check_digit(letters:str,digits:str)-str: 计算香港身份证号码的校验码 letters: 开头字母部分1-2个大写字母 digits: 6位数字字符串 返回: 校验码0-9 或 A # 1. 构建完整的8位值序列不含校验码位# 字母转数字A10 ... Z35values[]iflen(letters)1:values.append(36)# 单字母时前面补空格36values.append(ord(letters[0])-ord(A)10)else:# 双字母values.append(ord(letters[0])-ord(A)10)values.append(ord(letters[1])-ord(A)10)# 2. 数字部分forchindigits:values.append(int(ch))# 3. 加权求和权重从9开始递减weights[9,8,7,6,5,4,3,2]totalsum(v*wforv,winzip(values,weights))# 4. 取余remaindertotal%11# 5. 校验码规则ifremainder0:return0elifremainder1:returnAelse:returnstr(11-remainder)defvalidate_hkid(hkid:str)-bool:完整验证香港身份证号码格式 校验码parsedparse_hkid(hkid)ifnotparsed:returnFalseletters,digits,check_digitparsed calculatedcalculate_hkid_check_digit(letters,digits)returncalculatedcheck_digit# 测试print(calculate_hkid_check_digit(A,123456))# 3print(validate_hkid(A123456(3)))# Trueprint(validate_hkid(A123456(9)))# False校验码不对收藏提示②validate_hkid这个函数是两层验证的完整实现——第一层正则查格式第二层 mod 11 查校验码。直接用validate_hkid()就能判断一个香港身份证号码是否逻辑有效。注意逻辑有效 ≠ 真实存在它只能证明号码结构正确不能证明这个身份证真的发给了某个人。三、香港车牌格式传统 vs 自定义香港车牌有两种格式完全不同传统车牌1-2 个字母 1-4 位数字如AB 1234、A 1。自定义车牌2006年起最多 8 个字符可以是字母数字空格的任意组合如MYCAR、L0VE U。# 传统车牌1-2字母 1-4数字可能有空格分隔TRADITIONAL_PLATEre.compile(r^([A-Z]{1,2})\s?(\d{1,4})$)# 自定义车牌最多8个字符字母/数字/空格CUSTOM_PLATEre.compile(r^[A-Z0-9 ]{1,8}$)defparse_plate(plate:str)-str:识别香港车牌类型plateplate.strip().upper()ifTRADITIONAL_PLATE.match(plate):returnf传统车牌:{plate}elifCUSTOM_PLATE.match(plate):returnf自定义车牌:{plate}return无效车牌print(parse_plate(AB 1234))# 传统车牌print(parse_plate(MYCAR))# 自定义车牌print(parse_plate(ABC12345))# 无效9个字符超限四、香港电话号码格式香港电话号码统一 8 位数字但不同号段有不同含义固话通常 2 或 3 开头手机4/5/6/9 开头国际格式852前缀# 8位数字可带 852 或 00852 国际前缀PHONE_PATTERNre.compile(r^(?:\852|00852)?\s?([2-9]\d{7})$)defparse_phone(phone:str)-str:解析香港电话号码mPHONE_PATTERN.match(phone.strip())ifnotm:return无效电话号码numberm.group(1)prefixnumber[0]ifprefixin23:returnf固话:{number}elifprefixin4569:returnf手机:{number}else:returnf其他:{number}print(parse_phone(852 2345 6789))# 固话print(parse_phone(98765432))# 手机9开头print(parse_phone(12345678))# 无效1开头且只有7位数字五、完整验证器可直接复用把三个验证器整合成一个工具类importreclassHKDataValidator:香港身份证/车牌/电话格式验证器# 身份证HKID_PATTERNre.compile(r^([A-Z]{1,2})(\d{6})[(]([0-9A])[)]$)# 车牌TRADITIONAL_PLATEre.compile(r^([A-Z]{1,2})\s?(\d{1,4})$)CUSTOM_PLATEre.compile(r^[A-Z0-9 ]{1,8}$)# 电话PHONE_PATTERNre.compile(r^(?:\852|00852)?\s?([2-9]\d{7})$)staticmethoddef_letter_to_num(ch:str)-int:returnord(ch)-ord(A)10classmethoddefvalidate_hkid(cls,hkid:str)-bool:mcls.HKID_PATTERN.match(hkid.strip().upper())ifnotm:returnFalseletters,digits,check_digitm.group(1),m.group(2),m.group(3)# 构建值序列iflen(letters)1:values[36,cls._letter_to_num(letters[0])]else:values[cls._letter_to_num(letters[0]),cls._letter_to_num(letters[1])]values[int(ch)forchindigits]# 加权求和weights[9,8,7,6,5,4,3,2]totalsum(v*wforv,winzip(values,weights))remaindertotal%11# 校验码ifremainder0:calculated0elifremainder1:calculatedAelse:calculatedstr(11-remainder)returncalculatedcheck_digitclassmethoddefvalidate_plate(cls,plate:str)-bool:plateplate.strip().upper()returnbool(cls.TRADITIONAL_PLATE.match(plate)orcls.CUSTOM_PLATE.match(plate))classmethoddefvalidate_phone(cls,phone:str)-bool:returnbool(cls.PHONE_PATTERN.match(phone.strip()))# 使用示例validatorHKDataValidator()print(validator.validate_hkid(A123456(3)))# Trueprint(validator.validate_hkid(A123456(9)))# Falseprint(validator.validate_plate(AB 1234))# Trueprint(validator.validate_phone(852 9876 5432))# True六、三个易错点坑1全角括号香港用户用中文输入法时括号经常是全角。如果你只写\(...\)半角会漏掉一大批真实数据。正则里同时匹配半角和全角用[(]和[)]。坑2字母转数字的偏移量字母 A 对应数字10不是 1。这是最容易写错的地方——如果你用ord(ch) - ord(A) 1A 会变成 1整个校验码全错。正确是 10# ❌ 错误A1# ✅ 正确A10def_letter_to_num(ch):returnord(ch)-ord(A)10坑3逻辑有效 ≠ 真实存在校验码算法只能证明这个号码的结构是自洽的校验码和前面的字符对得上。它不能证明这个身份证真的发给了某个人。真正的身份核验需要调政府接口或人工核对正则和校验码只是第一道防线。收藏提示③三个坑里全角括号和字母偏移是最容易在真实项目里踩的。字母 A10 不是 A1——这个偏移量错了整个校验码算法就崩了。七、总结正则表达式能解决的是格式对不对。校验码算法能解决的是号码逻辑真不真。香港身份证号码恰好是两者的完美结合——格式1-2字母6数字校验码适合正则校验码mod 11 加权适合算法验证。三个东西记住正则验证格式校验码验证逻辑——两层验证缺一不可这是数据校验的通用思路香港身份证 A10 不是 A1——字母转数字的偏移量是最容易写错的细节全角括号是真实数据里的坑——中文输入法下半角正则匹配不到全角括号这篇文章是0810那篇数据清洗的自然延续——0810讲的是怎么处理Big5编码这篇讲的是怎么校验数据格式。两者合起来才是完整的香港数据清洗与验证闭环。本文为 Python 正则表达式与校验码算法的技术分享。香港身份证校验码算法为公开标准mod 11 加权文中示例号码均为演示用途的假号码不涉及任何真实个人数据。本文不构成任何身份核验建议。

相关新闻

Kodi 字幕下载太折腾?这款免费字幕插件 5 分钟解决找字幕难题

Kodi 字幕下载太折腾?这款免费字幕插件 5 分钟解决找字幕难题

Kodi 字幕下载太折腾?这款免费字幕插件 5 分钟解决找字幕难题 【免费下载链接】zimuku_for_kodi Kodi 插件,用于从「字幕库」网站下载字幕 项目地址: https://gitcode.com/gh_mirrors/zi/zimuku_for_kodi 每次打开 Kodi 准备看一部新美剧&#xf…

2026/10/15 9:48:49 阅读更多 →
「音画同生」时代开启:2026 年 8 月 AI 视频生成四大发布复盘

「音画同生」时代开启:2026 年 8 月 AI 视频生成四大发布复盘

过去一年,AI 视频长期停留在「画面生成 后期配音」的拼接阶段:镜头之间人物漂移、声音与画面不同步、每秒成本居高不下。2026 年 8 月,四款代表性发布的密集落地,第一次把「原生同步音频」从卖点变成了行业默认方向。本文用可溯源…

2026/10/15 9:48:49 阅读更多 →
家庭实验室HTTPS通配符证书自动化部署指南:基于acme.sh与DNS验证

家庭实验室HTTPS通配符证书自动化部署指南:基于acme.sh与DNS验证

你是否也曾在家庭实验室(Homelab)中为多个子域名配置 HTTPS 证书而头疼?每次新增一个nextcloud.home.lab或portainer.home.lab服务,都要重复申请、部署证书,不仅繁琐,还容易因为证书过期导致服务中断。更令…

2026/10/11 23:26:21 阅读更多 →

最新新闻

频谱分析仪选型与核心参数解析:N9020B/N9030A对比指南

频谱分析仪选型与核心参数解析:N9020B/N9030A对比指南

1. 频谱分析仪基础认知与选型指南在射频测试测量领域,频谱分析仪就像工程师的"电子显微镜",能够将看不见的电磁信号转化为可视化的频谱图形。是德科技(Keysight)的N9020B、安捷伦(Agilent)N9020A…

2026/10/15 9:48:45 阅读更多 →
工具过载时代的caveman思维:用最原始的方法高效解决问题

工具过载时代的caveman思维:用最原始的方法高效解决问题

上周六凌晨两点,我在生产环境里排查一个数据对不上的问题。链路里用了三套中间件、五个微服务,日志平台里的调用链视图看起来一切正常,可最终落库的数字就是和账本差了几百条。我盯着APM面板上花花绿绿的曲线,突然意识到自己这十年…

2026/10/15 9:48:45 阅读更多 →
Python实现网页自动化归档与长截图工具开发

Python实现网页自动化归档与长截图工具开发

1. 项目背景与核心价值最近在整理技术文档时发现一个痛点:很多优质的技术文档站点会突然关闭或改版,导致之前收藏的链接失效。更麻烦的是,有些文档内容需要以完整长图形式保存便于分享或打印。市面上的网页保存工具要么功能单一,要…

2026/10/15 9:48:44 阅读更多 →
npx陌生命令排查指南:从impeccable误报看CLI可信性诊断

npx陌生命令排查指南:从impeccable误报看CLI可信性诊断

1. 项目概述:一个被误读的“完美”工具名,以及它背后真实的CLI生态位最近在多个技术社区和前端开发者群聊里,“impeccable”这个词频繁跳出——不是作为形容词用在代码评审里夸人“写得无可挑剔”,而是作为一个具体可执行的命令出…

2026/10/15 9:48:44 阅读更多 →
hyperframes:高帧率视频处理的帧组架构与工程实践

hyperframes:高帧率视频处理的帧组架构与工程实践

1. 为什么我会盯上 hyperframes 这个方向hyperframes 这个词,我第一次看到是在一个客户的招标参数里,他们要做高速机械臂的视觉引导,要求抓拍速度到120fps,而且不能丢帧。我当时第一反应是:直接堆硬件不就完事了&#…

2026/10/15 9:48:44 阅读更多 →
2026东莞离婚纠纷维权优选:广东卡夫律所本土裁判优势深度解析

2026东莞离婚纠纷维权优选:广东卡夫律所本土裁判优势深度解析

2026东莞离婚纠纷维权优选:广东卡夫律所本土裁判优势深度解析在婚姻家事纠纷处理中,不同于普通民商事案件的刚性法条适用,离婚诉讼更看重本地法院裁判尺度、家事审判惯例、法官自由裁量标准。2026年东莞家事司法审判日趋精细化,抚…

2026/10/15 9:47:44 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →