首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将utf16 csv转换为数组

将utf16 csv转换为数组
EN

Stack Overflow用户
提问于 2014-08-02 16:32:57
回答 2查看 364关注 0票数 0

我尝试将一个用UTF-16 (由另一个程序导出)编码的CSV文件转换为Python 2.7中的一个简单数组,但运气很差。

下面是我找到的最近的解决方案:

代码语言:javascript
复制
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 .

我想得到的是这样的东西:

代码语言:javascript
复制
[['','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。

能帮我一把吗?谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-02 16:55:43

第1项:十六进制字符

你得到的是:

代码语言:javascript
复制
[' \tNombre\tEtiqueta\tExtensi\xc3\xb3n de archivo\tTama\xc3\xb1ol\xc3\xb3gico\tCategor\xc3\xada']

输出是因为您正在打印一个list。列表的行为是打印每个项目的表示形式。也就是说,它相当于:

代码语言:javascript
复制
print('[{0}]'.format(','.join[repr(item) for item in lst]))

如果使用print(line[0]),您将得到行的输出。

第2项:输出

这里的问题是csv解析器并不是将内容解析为一个选项卡分隔的文件,而是一个逗号分隔的文件。您可以通过以下方法修复这个问题:

代码语言:javascript
复制
for line in csv.reader(BytesIO(s), delimiter='\t'):
    print(line)

而不是。

这将给你想要的结果。

票数 0
EN

Stack Overflow用户

发布于 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值,可以在迭代时使用额外的生成器:

代码语言:javascript
复制
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码点都将由转义代码表示:

代码语言:javascript
复制
>>> [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字符串编码为与终端编码相匹配的字节,从而使终端再次显示正确的字符串:

代码语言:javascript
复制
>>> u'Extensi\xf3n de archivo'
u'Extensi\xf3n de archivo'
>>> print u'Extensi\xf3n de archivo'
Extensión de archivo

演示:

代码语言:javascript
复制
>>> 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ía
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25097166

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档