我正在解析一个包含一些UTF-16编码字符串的文档。
我有一个字节串,其中包含以下内容:
my_var = b'\xc3\xbe\xc3\xbf\x004\x004\x000\x003\x006\x006\x000\x006\x00-\x001\x000\x000\x003\x008\x000\x006\x002\x002\x008\x005'
当转换为utf-8时,我得到以下输出:
print(my_var.decode('utf-8'))
#> þÿ44036606-10038062285
前两个字符þÿ表示这是UTF-16BE的BOM,如维基百科所示
但是,我不明白的是,如果我尝试使用UTF16 BOM,就像这样:
if value.startswith(codecs.BOM_UTF16_BE)
这将返回false。实际上,打印codecs.BOM_UTF16_BE
不会显示相同的结果:
print(codecs.BOM_UTF16_BE)
#> b'\xfe\xff'
为什么会这样呢?我怀疑高端存在一些编码问题,但不确定如何解决。
在Stackoverflow上已经有几篇关于如何解码UTF-16的文章(例如这篇),它们都说同一件事:使用utf-16
进行解码,Python会处理BOM。
... 但对我来说并没有用。
print(my_var.decode('utf-16')
#> 뻃뿃㐀㐀 ㌀㘀㘀 㘀ⴀ ㌀㠀 㘀㈀㈀㠀㔀
但是使用UTF-16BE编码方式:
print(my_var.decode('utf-16be')
#> 쎾쎿44036606-10038062285
(BOM未被移除)
(使用UTF-16LE)
print(my_var.decode('utf-16le')
#> 뻃뿃㐀㐀 ㌀㘀㘀 㘀ⴀ ㌀㠀 㘀㈀㈀㠀㔀
出于我无法解释的原因,仅使用.decode('UTF-16')
不能正常工作。为什么?
更新
原始源字符串不是我提到的那个,而是这一个:
source = '\376\377\0004\0004\0000\0003\0006\0006\0000\0006\000-\0001\0000\0000\0003\0008\0000\0006\0002\0002\0008\0005'
我使用以下方式进行转换:
def decode_8bit(cls, match):
value = match.group().replace(b'\\', b'')
return chr(int(value, base=8)).encode('utf-8')
my_var = re.sub(b'\\\\[0-9]{1,3}', decode_8bit, source)
也许我在这里做错了什么?
print(...)
的结果并不是一种有效的检查编码方式,因为print
可能无法打印某些字符,所以您不应该信任它。 - Giacomo Alzetta