utf-16be编码后用utf-8解码无报错但JSON解析失败等问题咨询
Python跨编码场景的问题解析
1. 为何跨编码解码不报错?
UTF-8的解码逻辑自带容错性,只要输入的字节序列不是完全违反UTF-8编码规则的无效序列,它就会尝试把每个字节(或字节组)解析成对应的Unicode字符——哪怕这个字节序列原本是用其他编码(比如UTF-16BE)生成的。比如UTF-16BE是双字节编码,用UTF-8解码时会把这些双字节拆成单个或多个UTF-8字符(多为不可见控制字符),但不会触发解码错误。
2. 打印正常却JSON解析失败?
打印时,跨编码解码出来的不可见控制字符(比如零宽字符、非打印控制码)不会被终端显示,看起来和正常的{"foo": "bar"}完全一致,但这些隐藏字符实际存在于字符串中。JSON解析器对字符有严格规范,不允许包含这类不符合标准的控制字符,因此解析时会直接失败。
3. 写入文件后被识别为二进制的原因?
解码后的字符串包含非ASCII的控制字符,写入文件时这些字符会被转成对应的UTF-8字节。less命令会检测文件的字节特征,一旦发现存在无法识别为可打印UTF-8字符的字节序列(比如开头的非标准起始字节、不可见控制码),就会判定为二进制文件。
4. 如何查看decoded_str的原始形态?
有几种实用方法:
- 用
repr()函数打印:执行print(repr(decoded_str)),会显示转义后的字符(比如\x00、\u0000这类形式); - 遍历字符打印Unicode码点:
for char in decoded_str: print(f"{char}: {ord(char)}") - 转成十六进制字节查看:执行
print(decoded_str.encode('utf-8').hex()),能看到字符串对应UTF-8字节的十六进制形式; - 查看字符名称:借助
unicodedata模块:import unicodedata for char in decoded_str: print(f"{char}: {unicodedata.name(char, '无法识别的字符')}")
内容的提问来源于stack exchange,提问作者Vishesh Mukherjee
相关产品推荐
相关产品推荐

