您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

一个针对非ASCII的弹性,实际工作的CSV实现?

一个针对非ASCII的弹性,实际工作的CSV实现?

您正在尝试将解决方案应用于 问题。注意:

def utf_8_encoder( )

您正在喂它的str对象。

读取非ASCII CSV文件的问题是您不知道编码,也不知道定界符。如果您确实知道编码(并且它是基于ASCII的编码(例如cp125x,任何东亚编码,UTF-8, 不是 UTF-16, 不是 UTF-32))和定界符,那么它将起作用:

for row in csv.reader("foo.csv", delimiter=kNown_delimiter):
   row = [item.decode(encoding) for item in row]

您的sample_euro.csv看起来像带逗号分隔符的cp1252。俄语看起来像带有分号分隔符的cp1251。顺便说一句,从内容看来,您还需要确定所使用的日期格式,也可能要确定货币- 俄罗斯的示例中包含货币金额,后跟一个空格,并用西里尔字母表示“卢布”。

请仔细注意:阻止所有试图说服您具有ISO-8859-1编码文件的尝试。它们在cp1252中编码。

以回应评论“”。如果我理解您的意思,则必须知道编码才能使其正常工作?在一般情况下,我将不知道编码,并且基于其他答案,猜测编码非常困难,所以我不走运吗?“”“

您必须知道编码才能正常进行 文件阅读练习。

对于任何大小的文件中的任何编码,始终可以正确地猜测编码不是很困难-这是不可能的。但是,将范围限制为使用用户区域设置的认编码从Excel或Open Office中保存的csv文件,并且大小合理,这并不是一件大事。我建议您尝试一下chardet。它会windows-1252为您的欧元文件windows-1251俄罗斯文件进行猜测- 考虑到它们的体积很小,这是一个了不起的成就。

响应“”“ 将是最受欢迎的”“”

工作代码(Python 2.x):

from chardet.universaldetector import UniversalDetector
chardet_detector = UniversalDetector()

def charset_detect(f, chunk_size=4096):
    global chardet_detector
    chardet_detector.reset()
    while 1:
        chunk = f.read(chunk_size)
        if not chunk: break
        chardet_detector.Feed(chunk)
        if chardet_detector.done: break
    chardet_detector.close()
    return chardet_detector.result

# Exercise for the reader: replace the above with a class

import csv    
import sys
from pprint import pprint

pathname = sys.argv[1]
delim = sys.argv[2] # allegedly kNown
print "delim=%r pathname=%r" % (delim, pathname)

with open(pathname, 'rb') as f:
    cd_result = charset_detect(f)
    encoding = cd_result['encoding']
    confidence = cd_result['confidence']
    print "chardet: encoding=%s confidence=%.3f" % (encoding, confidence)
    # insert actions contingent on encoding and confidence here
    f.seek(0)
    csv_reader = csv.reader(f, delimiter=delim)
    for bytes_row in csv_reader:
        unicode_row = [x.decode(encoding) for x in bytes_row]
        pprint(unicode_row)

输出1:

delim=',' pathname='sample-euro.csv'
chardet: encoding=windows-1252 confidence=0.500
[u'31-01-11',
 u'Overf\xf8rsel utland',
 u'UTLBET; ID 9710032001647082',
 u'1990.00',
 u'']
[u'31-01-11',
 u'Overf\xf8ring',
 u'OVERF\xd8RING MELLOM EGNE KONTI',
 u'5750.00',
 u';']

输出2:

delim=';' pathname='sample-russian.csv'
chardet: encoding=windows-1251 confidence=0.602
[u'-',
 u'04.02.2011 23:20',
 u'300,00\xa0\u0440\u0443\u0431.',
 u'',
 u'\u041c\u0422\u0421',
 u'']
[u'-',
 u'04.02.2011 23:15',
 u'450,00\xa0\u0440\u0443\u0431.',
 u'',
 u'\u041e\u043f\u043b\u0430\u0442\u0430 Interzet',
 u'']
[u'-',
 u'13.01.2011 02:05',
 u'100,00\xa0\u0440\u0443\u0431.',
 u'',
 u'\u041c\u0422\u0421 kolombina',
 u'']

这些文件的来源是什么?如果从Excel或OpenOffice Calc或Gnumeric中将它们“另存为CSV”,则可以通过将它们另存为“ Excel 97-2003工作簿(* .xls)”并使用xlrd读取它们来避免整个编码过程。这也省去了必须检查每个csv文件以确定定界符(逗号与分号),日期格式(2011年1月31日与2011年4月2日)和“小数点”(5750.00与450,00)的麻烦- - 所有这些差异大概是通过另存为CSV来创建的 。免责声明:我是的作者xlrd

其他 2022/1/1 18:43:28 有577人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶