UTF-16转Ascii,忽略小于127的字符

2 投票
3 回答
5079 浏览
提问于 2025-04-16 19:38

我知道这个问题有很多解决方案,但我遇到的情况有点特殊,因为我可能会得到被截断的utf16数据,而我还得尽力处理这些转换。在这种情况下,解码和编码可能会出现UnicodeDecodeError错误。所以我写了下面的Python代码。请告诉我你们有什么建议,可以让我处理得更快。

    try:
        # conversion to ascii if utf16 data is formatted correctly
        input = open(filename).read().decode('UTF16')
        asciiStr = input.encode('ASCII', 'ignore')
        open(filename).close()
        return asciiStr
    except:
        # if fail with UnicodeDecodeError, then use brute force 
        # to decode truncated data
        try:
            unicode = open(filename).read()
            if (ord(unicode[0]) == 255 and ord(unicode[1]) == 254):
                print("Little-Endian format, UTF-16")
                leAscii = "".join([(unicode[i]) for i in range(2, len(unicode), 2) if 0 < ord(unicode[i]) < 127])
                open(filename).close()
                return leAscii
            elif (ord(unicode[0]) == 254 and ord(unicode[1]) == 255):
                print("Big-Endian format, UTF-16")
                beAscii = "".join([(unicode[i]) for i in range(3, len(unicode), 2) if 0 < ord(unicode[i]) < 127])
                open(filename).close()
                return beAscii
            else:
                open(filename).close()
                return None
        except:
            open(filename).close()
            print("Error in converting to ASCII")
            return None

3 个回答

-1

我觉得这个建议真是个“最佳实践”的提升。文件的操作最好用with语句来包裹起来。这样可以自动帮你打开文件并在用完后清理,省去很多麻烦。

3

那这样怎么样:

data = open(filename).read()
try:
    data = data.decode("utf-16")
except UnicodeDecodeError:
    data = data[:-1].decode("utf-16")

也就是说,如果在一个代码单元中间被截断了,就把最后一个字节去掉,然后再试一次。这样应该能让你得到一个有效的UTF-16字符串,而不需要自己去实现解码器。

2

为了处理错误,你可以使用字节字符串的解码方法中的可选第二个参数。在这个例子中,多余的第三个字节('c')被替换成了“替代字符”U+FFFD:

>>> 'abc'.decode('UTF-16', 'replace')
u'\u6261\ufffd'

还有一个“忽略”选项,它会直接丢掉那些无法解码的字节:

>>> 'abc'.decode('UTF-16', 'ignore')
u'\u6261'

虽然我们常常希望系统能够“容忍”编码不正确的文本,但实际上很难准确地定义在这些情况下应该如何处理。你可能会发现,提出“处理”编码不正确的文本要求的人,并不完全理解字符编码的概念。

撰写回答