我尝试将一个用UTF-16 (由另一个程序导出)编码的CSV文件转换为Python 2.7中的一个简单数组,但运气很差。
下面是我找到的最近的解决方案:
from io import BytesIO
with open ('c:\\pfm\\bdh.txt','rb') as f:
x = f.read().decode('UTF-16').encode('UTF-8')
for line in csv.reader(BytesIO(x)):
print line此代码返回:
采购产品名称: archivo\tTama\xc3\xb1ol\xc3\xb3gico\tCategor\xc3\xada''1\tnom1\tetq1\text1 .
我想得到的是这样的东西:
[['','Nombre','Etiqueta','Extensión de archivo','Tamaño lógico','Categoría']
['1','nom1','etq1','ext1','123','cat1']
['2','nom2','etq2','ext2','456','cat2']]因此,我需要将这些十六进制字符转换为拉丁文类型(as:á,é,í,ó,ú,or ),并将那些以制表符分隔的字符串转换为数组字段。
我真的需要在第一部分使用字典吗?我认为应该有一个更简单的解决方案,因为我可以看到和写所有这些字符通过键盘。
对于第二部分,我认为CSV库在这种情况下不会有帮助,因为我读到它还不能管理UTF-16。
能帮我一把吗?谢谢!
发布于 2014-08-02 16:55:43
第1项:十六进制字符
你得到的是:
[' \tNombre\tEtiqueta\tExtensi\xc3\xb3n de archivo\tTama\xc3\xb1ol\xc3\xb3gico\tCategor\xc3\xada']输出是因为您正在打印一个list。列表的行为是打印每个项目的表示形式。也就是说,它相当于:
print('[{0}]'.format(','.join[repr(item) for item in lst]))如果使用print(line[0]),您将得到行的输出。
第2项:输出
这里的问题是csv解析器并不是将内容解析为一个选项卡分隔的文件,而是一个逗号分隔的文件。您可以通过以下方法修复这个问题:
for line in csv.reader(BytesIO(s), delimiter='\t'):
print(line)而不是。
这将给你想要的结果。
发布于 2014-08-02 17:33:15
用Python2中的csv模块处理UTF-16文件确实很痛苦。重新编码到UTF-8可以工作,但是您仍然需要对结果列进行解码以生成unicode值。
还请注意,您的数据似乎是以制表符分隔的;默认情况下,csv.reader()使用逗号而不是制表符分隔列。您需要通过在构造读取器时设置delimiter='\t'来将其配置为使用制表符。
使用io.open()读取UTF-16并生成unicode行.然后,您可以使用codecs.iterencode()将已解码的unicode值从UTF-16文件转换为UTF-8。
要将行解码回unicode值,可以在迭代时使用额外的生成器:
import csv
import codecs
import io
def row_decode(reader, encoding='utf8'):
for row in reader:
yield [col.decode('utf8') for col in row]
with io.open('c:\\pfm\\bdh.txt', encoding='utf16') as f:
wrapped = codecs.iterencode(f, 'utf8')
reader = csv.reader(wrapped, delimiter='\t')
for row in row_decode(reader):
print row每一行仍将对每个包含的值使用repr(),这意味着您将看到Python文字语法来表示字符串。任何不可打印或非ASCII码点都将由转义代码表示:
>>> [u'', u'Nombre', u'Etiqueta', u'Extensión de archivo', u'Tamaño lógico', u'Categoría']
[u'', u'Nombre', u'Etiqueta', u'Extensi\xf3n de archivo', u'Tama\xf1o l\xf3gico', u'Categor\xeda']这是正常的;输出作为调试辅助工具是有用的,并且可以粘贴回任何Python会话来再现原始值,而不必担心终端编码。
例如,ó被表示为\xf3,表示Unicode代码点U+00F3拉丁文小写字母O加锐。如果要打印这一列,Python将将Unicode字符串编码为与终端编码相匹配的字节,从而使终端再次显示正确的字符串:
>>> u'Extensi\xf3n de archivo'
u'Extensi\xf3n de archivo'
>>> print u'Extensi\xf3n de archivo'
Extensión de archivo演示:
>>> import csv, codecs, io
>>> io.open('/tmp/demo.csv', 'w', encoding='utf16').write(u'''\
... \tNombre\tEtiqueta\tExtensi\xf3n de archivo\tTama\xf1o l\xf3gico\tCategor\xeda
... ''')
63L
>>> def row_decode(reader, encoding='utf8'):
... for row in reader:
... yield [col.decode('utf8') for col in row]
...
>>> with io.open('/tmp/demo.csv', encoding='utf16') as f:
... wrapped = codecs.iterencode(f, 'utf8')
... reader = csv.reader(wrapped, delimiter='\t')
... for row in row_decode(reader):
... print row
...
[u' ', u'Nombre', u'Etiqueta', u'Extensi\xf3n de archivo', u'Tama\xf1o l\xf3gico', u'Categor\xeda']
>>> # the row is displayed using repr() for each column; the values are correct:
...
>>> print row[3], row[4], row[5]
Extensión de archivo Tamaño lógico Categoríahttps://stackoverflow.com/questions/25097166
复制相似问题