【问题标题】:UTF-16 to Ascii ignoring characters with decimal value greater than 127UTF-16 到 Ascii 忽略十进制值大于 127 的字符
【发布时间】:2011-09-15 17:57:40
【问题描述】:

我知道这个问题有很多解决方案,但我的解决方案很奇怪,我可能会得到截断的 utf16 数据,但必须尽最大努力处理解码和编码将因 UnicodeDecodeError 失败的转换。于是想出了下面的python代码。 请让我知道您的 cmets 我如何改进它们以加快处理速度。

    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

【问题讨论】:

  • 顺便说一句,open(filename).close() 是浪费时间 - 它再次打开文件,然后立即关闭新的文件句柄。

标签: python ascii utf-16


【解决方案1】:

怎么样:

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

即如果它在代码单元的中途被截断,则剪掉最后一个字节,然后再做一次。这应该让您回到有效的 UTF-16 字符串,而不必自己尝试实现解码器。

【讨论】:

  • 这不会保护您免受对应于未分配代码点、保留代码点、代理代码点等的字节对的影响。
  • @wberry:不,但是如果您期望有效的 UTF-16 除非被截断,您可能希望这样做,这样您仍然会收到无效输入的错误。这个问题专门针对截断的 UTF-16。
【解决方案2】:

这只是作为一种“最佳实践”的改进让我大吃一惊。文件访问确实应该包含在with 块中。这将为您处理打开和清理工作。

【讨论】:

    【解决方案3】:

    为了容忍错误,您可以在字节串的解码方法中使用可选的第二个参数。在这个例子中,悬空的第三个字节('c')被替换为“替换字符”U+FFFD:

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

    还有一个“忽略”选项,它会简单地丢弃无法解码的字节:

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

    虽然通常希望系统能够“容忍”错误编码的文本,但通常很难准确定义在这些情况下的预期行为。您可能会发现提出“处理”错误编码文本要求的人并没有完全掌握字符编码的概念。

    【讨论】:

      猜你喜欢
      • 2021-06-05
      • 2017-05-03
      • 2014-06-20
      • 2020-01-18
      • 1970-01-01
      • 2014-10-17
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多