如何允许解码 UTF-8 字节数组?

How to permissively decode a UTF-8 bytearray?

我需要将存储在字节数组中的 UTF-8 序列解码为字符串。

UTF-8 序列可能包含错误部分。在这种情况下,我需要尽可能多地解码并(可选?)用“?”之类的内容替换无效部分。

# First part decodes to "ABÄC"
b = bytearray([0x41, 0x42, 0xC3, 0x84, 0x43])
s = str(b, "utf-8") 
print(s)

# Second part, invalid sequence, wanted to decode to something like "AB?C"
b = bytearray([0x41, 0x42, 0xC3, 0x43])
s = str(b, "utf-8")
print(s)

在 Python 3 中实现此目标的最佳方法是什么?

有几个内置的错误处理schemes for encoding and decoding str to and from bytes and bytearray with e.g. bytearray.decode()。例如:

>>> b = bytearray([0x41, 0x42, 0xC3, 0x43])

>>> b.decode('utf8', errors='ignore')  # discard malformed bytes
'ABC'

>>> b.decode('utf8', errors='replace')  # replace with U+FFFD
'AB�C'

>>> b.decode('utf8', errors='backslashreplace')  # replace with backslash-escape
'AB\xc3C'

此外,您可以编写自己的错误处理程序并register它:

import codecs

def my_handler(exception):
    """Replace unexpected bytes with '?'."""
    return '?', exception.end

codecs.register_error('my_handler', my_handler)

>>> b.decode('utf8', errors='my_handler')
'AB?C'

所有这些错误处理方案也可以与您问题中的 str() 构造函数一起使用:

>>> str(b, 'utf8', errors='my_handler')
'AB?C'

...虽然明确地使用 str.decode() 更为惯用。