我有CSV格式的数据,这些数据已经严重扰乱了字符编码,很可能在不同的软件应用程序之间来回传输(LibreOffice Calc,Microsoft,Excel,Google Refine,自定义PHP / MySQL软件;在Windows XP,Windows 7上和来自世界各地的GNU / Linux机器......)。似乎在这个过程中的某个地方,非ASCII字符已经变得严重混乱,我不确定如何解扰它们或检测模式。手动这样做会涉及几千条记录......
这是一个例子。对于“Trois-Rivières”,当我在Python中打开CSV文件的这一部分时,它说:
Trois-Rivi\xc3\x83\xc2\x85\xc3\x82\xc2\xa0res
问题:我可以通过什么程序撤销
\xc3\x83\xc2\x85\xc3\x82\xc2\xa0
回来
è
即。我怎么解读这个?这首先是如何被扰乱的?我该如何对这个错误进行逆向工程?
答案 0 :(得分:3)
您可以查看以下内容中提供的解决方案:Double-decoding unicode in python
另一个更简单的暴力解决方案是使用正则表达式(((\\\x[a-c0-9]{2}){8}))
搜索输入文件,在一小组加扰字符之间创建一个映射表。对于单个来源的文件,法语应少于32,德语少于10。然后,您可以使用此小映射表运行“查找和替换”。
答案 1 :(得分:2)
基于dan04's comment above,我们可以猜测字母“è”被错误地解释为“Š”,然后对其应用了 3倍 UTF-8编码。
那么,“è”如何变成“Š”呢?好吧,我有一种预感,最可能的解释是在两个不同的8位字符集之间,因此我在Wikipedia上查找了一些common character encodings,并找到了一个匹配项:CP850(以及其他各种相关的8位DOS code pages,例如CP851,CP853,CP857等),字母“è”被编码为字节0x8A,而在Windows-1252中则表示“Š”。
有了这些知识,我们可以使用简单的Unix shell命令行来重新创建这种曲折的错误编码链:
$ echo "Trois-Rivières" \
| iconv -t cp850 \
| iconv -f windows-1252 -t utf-8 \
| iconv -f iso-8859-1 -t utf-8 \
| iconv -f iso-8859-1 -t utf-8 \
| iconv -f ascii --byte-subst='\x%02X'
Trois-Rivi\xC3\x83\xC2\x85\xC3\x82\xC2\xA0res
在这里,第一个iconv
调用只是将字符串从我的本地字符编码(恰好是UTF-8)转换为CP850,而最后一个则只是使用Python风格的{ {1}}转义码。中间的三个\xNN
调用将重新创建应用于数据的 actual 重新编码步骤:首先从(假定)Windows-1252到UTF-8,然后从ISO-8859两次-1到UTF-8。
那么我们如何解决呢?好吧,我们只需要反向执行相同的步骤:
iconv
好消息是,此过程应该主要是可逆的。坏消息是,原始文本中的任何“ü”,“ì”,“Å”,“É”和“Ø”字母都可能不可逆地乱码,因为在Windows中未定义CP850中用于编码这些字母的字节-1252。 (如果幸运的话,它们可能被解释为与这些字节在ISO-8859-1中所表示的C1 control codes相同,在这种情况下,原则上应该可以进行反向转换。我没有设法弄清楚但是,如何说服$ echo -e 'Trois-Rivi\xC3\x83\xC2\x85\xC3\x82\xC2\xA0res' \
| iconv -f utf-8 -t iso-8859-1 \
| iconv -f utf-8 -t iso-8859-1 \
| iconv -f utf-8 -t windows-1252 \
| iconv -f cp850
Trois-Rivières
。)