python unicode错误转换为打印值

时间:2016-07-21 19:16:46

标签: python unicode

如果我有这样的unicode:

'\x00B\x007\x003\x007\x00-\x002\x00,\x001\x00P\x00W\x000\x000\x009\x00,\x00N\x00O\x00N\x00E\x00,\x00C\x00,\x005\x00,\x00J\x00,\x00J\x00,\x002\x009\x00,\x00G\x00A\x00R\x00Y\x00,\x00 \x00W\x00I\x00L\x00L\x00I\x00A\x00M\x00S\x00,\x00 \x00P\x00A\x00R\x00E\x00N\x00T\x00I\x00,\x00 \x00F\x00I\x00N\x00N\x00E\x00Y\x00 \x00&\x00 \x00L\x00E\x00W\x00I\x00S\x00,\x00U\x00S\x00,\x001\x00\r\x00'

它以字符串格式从csv读入,但我想将其转换为人类可读的形式。它在我打印它时起作用,但我似乎无法弄清楚方法命令,将其保存为人类可读形式的变量。什么是最好的方法?

1 个答案:

答案 0 :(得分:6)

你没有Unicode。不是还是。您有一系列字节,这些字节使用UTF-16 编码。您需要首先解码这些字节:

data.decode('utf-16-be')

打印它只是因为你的控制台忽略了每个UTF-16代码单元的大端对。

您的数据缺少Byte order mark,因此假设您在以下位置切割数据,我使用了UTF-16的utf-16-be big endian 变体正确的字节。如果你没有,它也可能是 little endian。

因为它是我必须删除最后\x00空字节以使其解码;当你将一个UTF-16代码单元(每2个字节)切成两半时,你粘贴了一个奇数而不是偶数个字节:

>>> s = '\x00B\x007\x003\x007\x00-\x002\x00,\x001\x00P\x00W\x000\x000\x009\x00,\x00N\x00O\x00N\x00E\x00,\x00C\x00,\x005\x00,\x00J\x00,\x00J\x00,\x002\x009\x00,\x00G\x00A\x00R\x00Y\x00,\x00 \x00W\x00I\x00L\x00L\x00I\x00A\x00M\x00S\x00,\x00 \x00P\x00A\x00R\x00E\x00N\x00T\x00I\x00,\x00 \x00F\x00I\x00N\x00N\x00E\x00Y\x00 \x00&\x00 \x00L\x00E\x00W\x00I\x00S\x00,\x00U\x00S\x00,\x001\x00\r\x00'
>>> s[:-1].decode('utf-16-be')
u'B737-2,1PW009,NONE,C,5,J,J,29,GARY, WILLIAMS, PARENTI, FINNEY & LEWIS,US,1\r'

您从中读取的文件可能包含BOM作为前两个字节。如果是这样,只需告诉您使用的任何内容来读取此数据以使用utf-16作为编解码器,并且它将从这些第一个字节中找出正确的变体。

如果您使用的是Python 2,那么您希望研究csv模块的Examples section,以获取可以以适合该模块的形式重新编码数据的代码;如果您包含该部分中的UnicodeReader,则可以像这样使用它:

with open(yourdatafile) as inputfile:
    reader = UnicodeReader(inputfile, encoding='utf-16')
    for row in reader:
        # row is now a list with unicode strings

演示:

>>> from StringIO import StringIO
>>> import codecs
>>> f = StringIO(codecs.BOM_UTF16_BE + s[:-1])
>>> r = UnicodeReader(f, encoding='utf-16')
>>> next(r)
[u'B737-2', u'1PW009', u'NONE', u'C', u'5', u'J', u'J', u'29', u'GARY', u' WILLIAMS', u' PARENTI', u' FINNEY & LEWIS', u'US', u'1']

如果您使用的是Python 3,只需将encoding参数设置为open()函数utf-16,然后按原样使用csv模块。