报表客户名看起来一样却匹配不上:用 unicodedata 统一 Unicode 形态并输出异常字符清单 #
文档明确的机制 #
Python 标准库 unicodedata 提供对 Unicode Character Database 的访问。给定文档页对应 Python 3.15.2,数据库编译自 UCD 17.0.0;它能查询字符名称、类别、数值属性,也能执行 Unicode 规范化。
报表里的客户名、SKU、账号在 CSV 或 Excel 导出后“肉眼相同”,代码比较却可能不相等。文档明确说明:同一个字符可能有多种表达方式,例如 U+00C7(带下加符的拉丁大写字母 C)也可表示为 U+0043 加 U+0327(组合下加符)。即使字符串已经规范化,若一个字符串含组合字符、另一个不含,也可能不相等。
unicodedata.normalize(form, unistr) 可返回指定正规形式,合法的 form 只有 NFC、NFD、NFKC、NFKD。其中 NFD 是规范分解,把字符转为分解形式;NFC 先规范分解,再重新组合预组合字符。NFKD 执行兼容分解,把兼容字符替换为等价物;NFKC 先兼容分解,再做规范组合。is_normalized(form, unistr) 可检查字符串是否处于指定形式,同样只接受这四种形式。
这四种形式不能混为“安全展示转换”。文档用罗马数字举例:U+2160(ROMAN NUMERAL ONE)因兼容既有字符集而存在,NFKD/NFKC 会按兼容等价处理。换言之,NFKC/NFKD 可能把兼容字符转换成另一串文本。团队若把转换结果直接覆盖客户原始名称,就可能改变原始语义或展示值。
异常清单可以直接使用文档列出的字符属性函数:name(chr) 返回字符名称;category(chr) 返回两字母通用类别;decomposition(chr) 返回分解映射;combining(chr) 返回规范组合类;east_asian_width(chr) 返回东亚宽度;decimal(chr)、digit(chr)、numeric(chr) 分别取得文档定义的十进制值、数字值和数值。文档示例显示,numeric('½') 返回 0.5,digit('SUPERSCRIPT NINE') 返回 9,但 decimal('SUPERSCRIPT NINE', -1) 返回默认值 -1。因此,“看起来像数字”的字符不应被统一假定具有同一类数值属性。
团队自行约定的接手建议(非 Python 文档承诺) #
以下是面向小团队入站处理 CSV/Excel 文本列的约定,不是 unicodedata 文档提供的完整流程。
团队建议:先检测,再按白名单转换,并保留原值。
- 保留原始字段:新增“原始客户名”“原始 SKU”“原始账号”等列,不把规范化结果回写成用户提交值。
- 先做形态检测:对同一列分别调用
is_normalized("NFC", s)、is_normalized("NFD", s)等检查,记录当前是否已处于目标形式。 - 生成匹配键时限定形式:可先约定团队使用 NFC 或 NFD 作为匹配键;涉及兼容字符时,NFKC/NFKD 只能进入白名单评估,不应默认批量执行。
- 输出逐字符清单:对仍未匹配的记录,按 Python 字符串位置列出码位、
name、category,必要时补充combining、decomposition、east_asian_width。 - 相似数字单独标注:对疑似数字字符分别尝试
decimal、digit、numeric,把无对应值或属性不同的情况写入异常,而不是自动改账。 - 白名单转换:只有团队确认某类兼容字符在本业务中可互换,才把对应 NFKC/NFKD 结果用于匹配键;每次转换都保留转换前后差异。
- emoji 与字形簇只做分段线索:Python 3.15 文档中的
iter_graphemes(unistr)按扩展字形簇规则迭代,可辅助定位用户可见字形;它不是业务分词规则,也不能证明两个字形簇在客户名或 SKU 中可互换。
交接产物建议包含三部分:规范化后的匹配字段、规范化前后仍不一致的记录、异常字符清单。清单至少保存字段名、行号、字符串位置、码位、字符名称和类别;若使用了数值属性,再记录具体函数和返回值。这样接手人可以复核“为什么没匹配上”,而不是只看到一个去重后的结果。
边界与总结 #
unicodedata 解决的是 Unicode 字符属性与正规形式问题。它不会替团队判断别名、错别字、字号差异、业务主体合并规则,也不会证明 NFKC/NFKD 后的文本仍应原样展示。尤其 NFKC/NFKD 基于兼容等价,可能改变字符序列;是否允许把全角/半角、兼容数字、罗马数字等视作同一业务键,必须由团队按字段和白名单决定。
因此,稳妥做法是:把文档明确给出的 NFC/NFD/NFKC/NFKD、is_normalized、name、category、数值属性和 iter_graphemes 用作检测与证据工具;把“先检测、白名单转换、保留原值、输出异常”限定为团队自己的接手约定。这样既能解释“看起来一样却匹配不上”的具体字符原因,也不会把可能改变语义的规范化结果误当作用户原始值。
相关工具 #
AI 工作流 ROI 诊断器 · 查看工具的输入要求、输出说明与适用范围。