奇怪的 csv.reader 行为 excel-exported csv

Strange csv.reader behaviour with excel-exported 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 mem\xc2\x85']
['', '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 mem\x85', '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是控制码,latin-1转unicode时表示"newline"。

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

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

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

经过大量挖掘,我找到了解决方案。在我上面的 EDIT2 中最后的 link 让我意识到一个我不知道存在的字符编码:"cp1252"。不幸的是,cp1252 中的 "normal" 字符等同于 iso-8859-2 "newline" 字符。因此,如果您明确地将 cp1252 编码文件读取为 iso-8859-2,您将在您不期望的地方获得换行符,这就是破坏 csv 解析器的原因。

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

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

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