奇怪的csv.reader行为与excel导出的csv



我一直在尝试解析从 Excel 保存的 csvs,发现默认情况下这些似乎是 ISO-8859-2(至少,chardet 有 80% 的把握这么认为),我可以让他们以这种方式解析。 但是在解析的版本中,一行被读出为两个单独的行。

我已经根据 csv 模块的文档设置了我的处理链,以使用正确的编码打开源文件,并通过 UTF8Recoder 运行它,以便在读入时将其转换为 UTF-8。

在概述中,它看起来像这样:

f = codecs.open("/path/to/csv", "r+b", encoding="ISO-8859-2")
reader = csv.reader(UTF8Recoder(f))
for row in reader: print row

对于单行的 CSV,这是输出 2 行!

通过命令行上的 vim 查看,csv 的内容是:

UCL,,,10.1016/j.neuropsychologia.xxxx,Elsevier,Neuropsychologia,DAT genotype modulates striatal processing and long-term mem<85>,091593/Z/10/Z,,,CC BY,

输出为

['UCL', '', '', '10.1016/j.neuropsychologia.xxxx', 'Elsevier', 'Neuropsychologia', 'DAT genotype modulates striatal processing and long-term memxc2x85']
['', '091593/Z/10/Z', '', '', 'CC BY', '']

如果我放弃所有字符编码处理,让库做任何他们想做的事情,我就不会得到这种行为。 相反,它似乎有效:

f = codecs.open("/path/to/csv", "r+b")
reader = csv.reader(f)
for row in reader: print row

输出为:

['UCL', '', '', '10.1016/j.neuropsychologia.xxxx', 'Elsevier', 'Neuropsychologia', 'DAT genotype modulates striatal processing and long-term memx85', '091593/Z/10/Z', '', '', 'CC BY', '']

谁能阐明正在发生的事情? (我注意到 \xc2\x85 变成了 \x85,如果这表示什么的话)

我宁愿将传入的数据显式编码为 UTF-8,这样我就不必担心应用程序中的其他任何地方,实际上我怀疑在导入过程中不指定编码会导致其他问题,如果我的字符编码经验是可以借鉴的!

任何提示非常感谢。

编辑:这似乎是相关的:http://www.voidspace.org.uk/python/weblog/arch_d7_2010_01_02.shtml

\x85 是一个控制代码,当拉丁语-1 转换为 Unicode 时,它的意思是"换行符"。

如果是这样,我想我需要一种方法来阻止这种情况发生。

编辑2:这也是相关的:http://mg.pov.lt/blog/latin1-or-cp1252

看起来

cp1252看起来很像iso-8859-1(又名拉丁语-1)。 我最初考虑过这一点,但将其称为"windows-1252"。 使用输入编码"cp1252"的初步调查看起来很有希望。

经过大量挖掘,我找到了解决这个问题的方法。 上面 EDIT2 中的最后一个链接让我意识到一个我不知道存在的字符编码:"cp1252"。 不幸的是,cp1252中的"正常"字符相当于iso-8859-2"换行符"。 因此,如果您将 cp1252 编码文件显式读取为 iso-8859-2,您将获得您意想不到的换行符,这就是破坏 csv 解析器的原因。

另请注意,尽管有明显的相似之处 windows-1252 和 cp1252 并不相同,至少在解析字节可能会导致一个异常而不是另一个异常 - 我没有任何关于这些编码之间的确切差异的细节。

另请注意,我最初根据对数据运行 chardet 对字符编码进行了 iso-8859-2 确定,这使我的编码概率为 80% - 这还不够高:)

对于我的软件中的长期解决方案,我列出了我期望从 csv 中获得的常见编码格式,并按可能性顺序尝试它们,直到我得到一个解析的格式,并输出我期望的形状的 csv(在这种情况下,正好是矩形) - 这两个部分都很重要,因为文件可能会使用错误的编码进行解析,但可能不会产生结构合理的 csv。