Python中如何解码混合字节与UTF-8格式的字符串?
解决CSV中混合字节与UTF-8格式字符串的解码问题
核心原因
你遇到的这类字符串,本质是Python字节对象的字符串表示形式(即repr(b'xxx')的输出结果被直接写入了CSV),所以不能直接对原字符串做编码解码操作,得先把它还原成真正的字节对象,再进行UTF-8解码。
可行解决方案
方法1:用ast.literal_eval安全解析(推荐)
ast.literal_eval能安全地将字符串形式的Python字面量转换成对应数据类型,不会执行恶意代码,比eval更可靠。
示例代码:
import ast import csv # 读取并处理CSV文件 with open('your_file.csv', 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for row in reader: # 假设目标列名为'city',先去除外层双引号 raw_city = row['city'].strip('"') try: # 解析为字节对象后解码 city_bytes = ast.literal_eval(raw_city) row['city'] = city_bytes.decode('utf-8') # 输出示例:Łódź, Poland print(row['city']) except (ValueError, SyntaxError): # 兼容已经是正常UTF-8格式的行 row['city'] = raw_city
方法2:手动处理转义字符(无依赖场景)
如果无法使用ast模块,可以手动剥离标识字符,再将转义的十六进制序列还原为字节:
def fix_mixed_encoding(s): # 移除外层双引号、b'前缀和末尾的' cleaned = s.strip('"').removeprefix("b'").removesuffix("'") # 将字符串中的转义序列转换为原始字节 byte_data = cleaned.encode('unicode_escape').decode('utf-8').encode('latin-1') return byte_data.decode('utf-8') # 测试示例 test_input = '"b\'\\xc5\\x81\\xc3\\xb3d\\xc5\\xba, Poland\'"' print(fix_mixed_encoding(test_input)) # 输出:Łódź, Poland
为什么之前的尝试无效?
- 直接执行
encode('utf-8').decode('utf-8')只是对原字符串做了一次无意义的编码解码循环,没有把字符串里的转义十六进制字符还原成真实字节,自然会出现乱码(比如Å\x81ódź)。 - 单纯替换
b'和双引号,没有处理\xc5这类转义序列——它们在当前字符串里是普通文本字符,不是真正的字节值,所以无法直接解码。
内容的提问来源于stack exchange,提问作者John Sweeney
相关产品推荐
相关产品推荐

