代码之家  ›  专栏  ›  技术社区  ›  Yuval Adam

Python字符串解码问题

  •  3
  • Yuval Adam  · 技术社区  · 14 年前

    我试图解析一个CSV文件,其中包含一些数据,主要是数字,但有一些字符串-我不知道他们的编码,但我知道他们在希伯来语。

    最后,我需要知道编码,这样我就可以对字符串进行unicode编码,打印它们,也许以后还可以将它们放入数据库。

    我试过用 Chardet ,声明字符串是Windows-1255( cp1255 print someString.decode('cp1255') 产生臭名昭著的错误:

    UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-4: ordinal not in range(128)
    

    你知道我如何正确解码这些字符串吗?


    编辑:

    print repr(sampleString)
    #prints:
    '\xe0\xe1\xe2\xe3\xe4'
    

    (使用Python 2.6.2)

    4 回复  |  直到 14 年前
        1
  •  12
  •   Community Egal    7 年前

    事情就是这样:

    • sampleString是字节字符串(cp1255编码)
    • sampleString.decode("cp1255") 解码(解码==字节->unicode字符串)将字节字符串转换为unicode字符串
    • print sampleString.decode("cp1255") 尝试将unicode字符串打印到标准输出。打印必须 编码 要执行此操作的unicode字符串(encode==unicode字符串->字节)。您看到的错误意味着python print语句无法将给定的unicode字符串写入控制台的编码。 sys.stdout.encoding

    所以问题是您的控制台不支持这些字符。您应该能够调整控制台以使用其他编码。具体操作方法取决于操作系统和终端程序。

    另一种方法是手动指定要使用的编码:

    print sampleString.decode("cp1255").encode("utf-8")
    

    另请参见:

    import sys
    print sys.stdout.encoding
    samplestring = '\xe0\xe1\xe2\xe3\xe4'
    print samplestring.decode("cp1255").encode(sys.argv[1])
    

    在我的utf-8终端上:

    $ python2.6 test.py utf-8
    UTF-8
    אבגדה
    
    $ python2.6 test.py latin1
    UTF-8
    Traceback (most recent call last):
    UnicodeEncodeError: 'latin-1' codec can't encode characters in position 0-4: ordinal not in range(256)
    
    $ python2.6 test.py ascii
    UTF-8
    Traceback (most recent call last):
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)
    
    $ python2.6 test.py cp424
    UTF-8
    ABCDE
    
    $ python2.6 test.py iso8859_8
    UTF-8
    �����
    

    拉丁1和ascii的错误消息意味着字符串中的unicode字符不能在这些编码中表示。

    http://docs.python.org/library/codecs.html#standard-encodings 支持希伯来文字符)。使用这些编码我也不例外,因为希伯来unicode字符在编码中有表示。

    但是,当我的utf-8终端接收到与utf-8不同编码的字节时,它会变得非常混乱。

    这个 encode 方法有一个可选的字符串参数,可用于指定当编码不能表示字符时应执行的操作( documentation add your own custom strategies

    另一个测试程序(我在字符串周围加引号以更好地显示ignore的行为):

    import sys
    samplestring = '\xe0\xe1\xe2\xe3\xe4'
    print "'{0}'".format(samplestring.decode("cp1255").encode(sys.argv[1], 
          sys.argv[2]))
    

    结果是:

    $ python2.6 test.py latin1 strict
    Traceback (most recent call last):
      File "test.py", line 4, in <module>
        sys.argv[2]))
    UnicodeEncodeError: 'latin-1' codec can't encode characters in position 0-4: ordinal not in range(256)
    [/tmp]
    $ python2.6 test.py latin1 ignore
    ''
    [/tmp]
    $ python2.6 test.py latin1 replace
    '?????'
    [/tmp]
    $ python2.6 test.py latin1 xmlcharrefreplace
    '&#1488;&#1489;&#1490;&#1491;&#1492;'
    [/tmp]
    $ python2.6 test.py latin1 backslashreplace
    '\u05d0\u05d1\u05d2\u05d3\u05d4'
    
        2
  •  3
  •   Mike Graham    14 年前

    将字符串解码为unicode时 someString.decode('cp1255') print ,您需要一个具体的、编码的、特定编码的表示。看来你的问题不在于解码,而在于 打印 .

    print someString 如果终端理解cp1255或“ print someString.decode('cp1255').encode('the_encoding_your_terminal_does_understand') print repr(someString.decode('cp1255')) 还可以获得抽象unicode字符串的有意义表示。

        3
  •  0
  •   Ignacio Vazquez-Abrams    14 年前

    你得到了一个 编码 chcp 65001

        4
  •  0
  •   user3850 user3850    14 年前

    someString sampleString ?

    >>> print '\xe0\xe1\xe2\xe3\xe4'.decode('cp1255')
    <hebrew characters>
    
    >>> print u'\xe0\xe1\xe2\xe3\xe4'.decode('cp1255')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "[...]/encodings/cp1255.py", line 15, in decode
        return codecs.charmap_decode(input,errors,decoding_table)
    UnicodeEncodeError: 'ascii' codec can't encode characters [...]