【问题标题】:Python Unicode hex string decodingPython Unicode 十六进制字符串解码
【发布时间】:2014-12-28 13:01:54
【问题描述】:

我有以下字符串: u'\xe4\xe7\xec\xf7 \xe4\xf9\xec\xe9\xf9\xe9' 在 windows-1255 中编码,我想将其解码为 Unicode 代码点(u' \u05d4\u05d7\u05dc\u05e7 \u05d4\u05e9\u05dc\u05d9\u05e9\u05d9')。

>>> u'\xe4\xe7\xec\xf7 \xe4\xf9\xec\xe9\xf9\xe9'.decode('windows-1255')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\encodings\cp1255.py", line 15, in decode
    return codecs.charmap_decode(input,errors,decoding_table)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

但是,如果我尝试解码字符串: '\xe4\xe7\xec\xf7 \xe4\xf9\xec\xe9\xf9\xe9' 我没有得到异常:

>>> '\xe4\xe7\xec\xf7 \xe4\xf9\xec\xe9\xf9\xe9'.decode('windows-1255')
u'\u05d4\u05d7\u05dc\u05e7 \u05d4\u05e9\u05dc\u05d9\u05e9\u05d9'

如何解码 Unicode 十六进制字符串(获得异常的字符串)或将其转换为可解码的常规字符串?

感谢您的帮助。

【问题讨论】:

    标签: python string python-2.7 unicode hex


    【解决方案1】:

    我有以下字符串:u'\xe4\xe7\xec\xf7 \xe4\xf9\xec\xe9\xf9\xe9' 编码为windows-1255

    这是自相矛盾的。 u 表示它是一个 Unicode 字符串。但是如果你说它是用什么编码的,那它一定是一个字节串(因为一个Unicode字符串只能编码成一个字节串)。

    确实 - 您给定的实体 - \xe4\xe7 等 - 每个都代表一个字节,并且只有通过给定的编码 windows-1255 他们才被赋予各自的含义。

    换句话说,如果您有u'\xe4',您可以确定它与u'\u00e4' 相同,而不是u'\u05d4',否则会出现这种情况。

    如果您有任何机会从不知道此问题的来源获得了错误的 Unicode 字符串,您可以从中派生出您真正需要的字节字符串:借助“1:1 编码”,它是拉丁语1。

    所以

    correct_str = u_str.encode("latin1")
    # now every byte of the correct_str corresponds to the respective code point in the 0x80..0xFF range
    correct_u_str = correct_str.decode("windows-1255")
    

    【讨论】:

    • “1:1编码”是什么意思?为什么u_str.encode("ascii") 失败而u_str.encode("latin1") 没有?
    • @stalk 使用 1:1 编码我想说这是一种将前 256 个 Unicode 代码点映射到 256 个可能字节的编码。也就是说,如前所述,latin1。 ascii 编码只覆盖 ASCII 范围,即 0..127。
    • ...值得一提的是,对于每个 ASCII 字符,Unicode 等价物具有相同的代码。因此,任何 ASCII 文本也是有效的 Unicode 文本。
    【解决方案2】:

    这是因为 \xe4\xe7\xec\xf7 \xe4\xf9\xec\xe9\xf9\xe9 是一个字节数组,而不是 Unicode 字符串:这些字节表示有效的 windows-1255 字符,而不是有效的 Unicode code points

    因此,在前面加上u 时,Python 解释器无法解码字符串,甚至无法打印:

    >>> print u'\xe4\xe7\xec\xf7 \xe4\xf9\xec\xe9\xf9\xe9'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
    

    因此,为了将字节数组转换为 UTF-8,您必须将其解码为 windows-1255,然后将其编码为 utf-8

    >>> '\xe4\xe7\xec\xf7 \xe4\xf9\xec\xe9\xf9\xe9'.decode('windows-1255')
                                                   .encode('utf8')
    '\xd7\x94\xd7\x97\xd7\x9c\xd7\xa7 \xd7\x94\xd7\xa9\xd7\x9c\xd7\x99\xd7\xa9\xd7\x99'
    

    这给出了原始的希伯来语文本:

    >>> print '\xd7\x94\xd7\x97\xd7\x9c\xd7\xa7 \xd7\x94\xd7\xa9\xd7\x9c\xd7\x99\xd7\xa9\xd7\x99'
    החלק השלישי
    

    【讨论】:

    • OP 有u'\xe4\xe7...' 字符串,而不是'\xe4\xe7...',我想他没有自己添加u
    • @stalk 该字符串以两种形式出现在 OP 中 - 带有和不带有 u 前缀。我认为这就是问题的重点。
    【解决方案3】:

    试试这个

    >> u'\xe4\xe7\xec\xf7 \xe4\xf9\xec\xe9\xf9\xe9'.encode('latin-1').decode('windows-1255')
    u'\u05d4\u05d7\u05dc\u05e7 \u05d4\u05e9\u05dc\u05d9\u05e9\u05d9'
    

    【讨论】:

      【解决方案4】:

      这样解码,

       >>> b'\xe4\xe7\xec\xf7 \xe4\xf9\xec\xe9\xf9\xe9'.decode('windows-1255')
          u'\u05d4\u05d7\u05dc\u05e7 \u05d4\u05e9\u05dc\u05d9\u05e9\u05d9'
      

      【讨论】:

        猜你喜欢
        • 2018-08-21
        • 2020-10-23
        • 2011-03-18
        • 2020-11-11
        • 2014-12-22
        • 1970-01-01
        • 1970-01-01
        • 2011-03-04
        • 1970-01-01
        相关资源
        最近更新 更多