不同编码下同字符串匹配失败:TSV读取名称与JSON键不匹配排查
编码匹配问题解决方法
问题根源
- 对照你提供的
hexdump输出和乱码显示,问题来源可以直接定位:TSV文件中的文本经历了两次“误将UTF-8字节流按Latin-1解码,再重新保存为UTF-8”的错误转码流程 - 正常人名里的ć字符,原始正确UTF-8编码仅为2个字节
c4 87,经过两次转码后,这个位置的字节膨胀为6个字节c3 83 c2 84 c3 82 c2 87,被pandas按UTF-8正常读入后,打印出来就会显示成乱码的Boro StjepanoviÃÂ,自然无法和JSON中存储的正确无乱码的键(如Boro Stjepanović)匹配
具体实现步骤
- 第一步:还原TSV中的乱码字符串。对读入的name列做反向解码操作,剥离两层转码错误,修改原有读取代码:
import pandas as pd df = pd.read_csv("example.tsv", header=0, sep='\t', encoding='utf-8') # 逐层剥离转码错误 df['name'] = df['name'].str.encode('latin1').str.decode('utf-8') df['name'] = df['name'].str.encode('latin1').str.decode('utf-8') names = df['name'].tolist()操作完成后可直接打印names列表验证,确认乱码文本已经还原为和JSON键一致的正常字符。如果转码过程中抛出解码错误,可循环重复上述操作,直到能正常解码出可读文本即可,不需要提前统计转码次数。
- 第二步:匹配前做Unicode标准化处理。部分带变音符号的字符存在视觉一致但Unicode编码序列不同的情况,即便还原了乱码,也可能因为编码差异导致匹配失败。需要对参与匹配的两侧字符串做统一的NFC标准化:
import json import unicodedata # 读取JSON文件,标准化所有键 with open("目标JSON文件路径", "r", encoding="utf-8") as f: json_content = json.load(f) normalized_json = { unicodedata.normalize("NFC", key): value for key, value in json_content.items() } # 标准化从TSV提取的名称列表 normalized_names = [unicodedata.normalize("NFC", name) for name in names] # 执行精确筛选 matched_data = { name: normalized_json[name] for name in normalized_names if name in normalized_json }
注意事项
- 反向还原转码时必须固定使用
latin1作为中间编码,因为Latin-1是单字节一一映射的编码,不会出现解码异常,可以完整还原经过多次转码的原始字节,换用其他编码大概率会触发解码错误 - 不要在匹配阶段引入模糊匹配、大小写折叠等额外逻辑,等编码问题彻底解决后再做精确匹配,避免出现非预期的错配
内容的提问来源于stack exchange,提问作者Paschalis
相关产品推荐
相关产品推荐

