从聊天记录批量提取快递单号并按快递公司分类:纯 Python 实跑踩坑记

2026-10-06 · 喵窝资源铺

场景:做客服或代发的人,微信记录、邮件、Excel 里粘着几十个快递单号,想按顺丰/圆通/中通分开去查件、打单、对账。手动一个个复制粘贴再筛选,比查件本身还费时间。这篇给一个纯标准库的 Python 脚本(track_classify.py):整段文本或 CSV 直接丢进去,自动提单号、按号段分类、去重、分组输出成每家一个文件,认不出的单号单独列出并标注置信度,绝不瞎猜。文中代码实跑验证,真实输出贴在下面。

它做的几件事

输入脚本的处理
聊天记录/邮件正文整段文本直接提取,不用先清洗格式
CSV 文件整个文件内容当文本扫,单号藏在哪列都能提
字母前缀单号SF/YT/STO/JT/JD/EMS 按前缀高置信分类
纯数字单号按号段分类,标注置信度(高/中/低)
重复单号去重保序,客户复制粘贴常态不产生重复打单
手机号自动排除,不会把 138xxxxxxxx 当成快递单号
认不出的进「未知」组,列出最可能候选但不强行归类
输出每家公司一个 txt:单号 + 识别依据 + 置信度

坑一:EMS 单号被通用数字正则「咬掉」前缀和 CN 尾

第一版先跑通用 \d{10,15} 抓数字,再跑各家前缀规则。EMS9876543210CN 被抓成 9876543210——前缀丢了,CN 尾也丢了,直接没法查件。

正解:先扫字母开头的完整单号模式(含 EMS 的 E+数字+CN 尾),纯数字兜底放最后。抓取顺序本身就是规则的一部分:

CODE = re.compile(r"(?

修复后 EMS9876543210CN 被完整抓成 EMS9876543210(实测保留前缀、去掉 CN 尾后仍是合法 EMS 单号格式)。

坑二:单号规则互相重叠,正则不设优先级就先到先得

中通 75 开头 12~14 位、韵达 4 开头 13 位、京东纯数字 11~15 位……这些号段互相有重叠。规则列表如果按字母序而不是按公司官方号段置信度排,一个数字单号可能被错误的规则抢先命中。

实测:第一版 44001234567891(韵达 13 位)因正则写死 4\d{12} 恰好是 13 位才没命中——换一个真实韵达 14 位单号就漏了。每条规则都带「依据 + 置信度」输出,让人一眼知道这个单号是靠什么规则归类的、可信度多少:

$ python track_classify.py input.txt --out classified
共提取 9 个单号(已去重)
  顺丰: 1 个 -> classified/顺丰.txt
  中通: 1 个 -> classified/中通.txt
  EMS: 1 个 -> classified/EMS.txt
  ...
注意: 未知/低置信单号已单独列出,请人工确认,勿直接打单

输出示例(classified/中通.txt):

75123456789012	75开12~14位	置信高

坑三:手机号被当快递单号

纯数字兜底规则 \d{10,15} 会把 13800138000(11 位手机号)和 20261006001(订单号)都抓进来。

实测抓到后修复:先标出文本里所有手机号的位置(1[3-9]\d{9}),纯数字命中这些位置的直接跳过:

PHONE = re.compile(r"1[3-9]\d{9}")
# 提取时跳过落在手机号区间内的纯数字命中

实测:

手机13812345678别抓 -> []          # 排除成功
订单20261006001 -> [('20261006001', None, '低')]  # 订单号没手机号特征,抓了但进低置信

纯数字单号没有手机号特征又没有公司规则命中的(比如订单号),宁可进低置信/未知让人复核,也不能当成确定单号去查件。

坑四:号段长度网上说的和真实单号对不上

网上查「中通单号位数」普遍说 12 位或 13 位,实测 75123456789012 是 14 位,44001234567891(韵达)13 位、YT7788112233445(圆通)14 位——各家公司号段长度本来就不是固定值,且会随时间扩展。

正解:规则写成区间而不是固定长度(如 75\d{10,12}、4\d{11,13}),并且宁可写宽松一点、输出里标置信度,也不要写死导致真单号漏抓。置信度中/低的照样输出,让人眼复核——漏抓比误报代价更大(漏了就永远没查件)。

坑五:重复单号不去重就重复打单

客服聊天记录里同一段单号被复制粘贴两三次是常态。不去重,打单就重复、对账就翻倍。

实测:同一段落贴两遍 75123456789012,第一版输出 2 条重复记录;改成 OrderedDict 去重保序后只出 1 条。再把提取结果整批追加回输入再跑一遍,结果完全一致(9 个单号不变)——幂等性顺带验证了:

first pass: 9  second pass: 9  identical: True

边界测试一览(实跑输出)

输入片段提取结果说明
SF1388555512345顺丰,置信高SF 前缀
YT4321123456789圆通,置信高YT 前缀
STO1234567890123申通,置信高STO 前缀
JT9100223344556极兔,置信高JT 前缀
JDV012345678901京东,置信高JDV 前缀
EMS9876543210CNEMS,置信高坑一修复后完整保留
75123456789012中通,置信高75 号段
44001234567891韵达,置信中4 号段
9399123456789邮政EMS,置信低9 号段,需人工复核
13800138000(排除)手机号
20261006001未知,置信低订单号,待人工确认
6222020200112233445(排除)19 位银行卡超出长度上限

CSV 输入同样可用:SF1234567890123、YT7788990123456 两行混合表格,各自正确归到顺丰/圆通。

使用

python track_classify.py 微信记录.txt 订单.csv --out classified
# 输出 classified/顺丰.txt、classified/圆通.txt ... classified/未知.txt

代码纯标准库,Python 3.8+ 直接跑,无需安装任何依赖。

喵窝资源铺提供代跑脚本服务:你把记录/文件发过来,跑完把分类结果发回你,¥5 起,虚拟物品不退款(跑不通不收费)。脚本本身免费自取。

📖 更多批量处理实战:博客目录 · 相邻文章:照片按 EXIF 日期归档 · Excel 批量提取手机号 · 微信群AA收款记录批量对账

脚本规则基于公开号段整理,快递公司号段可能随时间调整;识别结果仅供参考,查件前请以官方渠道为准。