3

我有 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

去取回

è

即我该如何解读这个?这怎么可能一开始就被打乱了?我怎样才能对这个错误进行逆向工程?

4

2 回答 2

3

您可以查看提供的解决方案:python 中的双解码 unicode

另一个更简单的蛮力解决方案是(((\\\x[a-c0-9]{2}){8}))在输入文件上使用正则表达式搜索在一小部分加扰字符之间创建一个映射表。对于单一来源的文件,法语应少于 32 个,德语应少于 10 个。然后您可以使用这个小映射表运行“查找和替换”。

于 2012-01-31T14:56:59.703 回答
2

根据上面dan04 的评论,我们可以猜测字母“è”不知何故被误解为“Š”,然后对其应用了三重UTF-8 编码。

那么“è”是如何变成“Š”的呢?好吧,我有一种预感,最有可能的解释是在两个不同的 8 位字符集之间,所以我在 Wikipedia 上查找了一些常见的字符编码,并找到了一个匹配项:在CP850(以及其他各种相关的 8 位DOS 代码中)页,例如 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

在这里,第一个调用只是将字符串从我的本地字符编码(恰好是 UTF-8)转换为 CP850,最后一个调用只是使用 Python 样式的转义码iconv对非 ASCII 字节进行编码。中间\xNN的三个调用重新创建了应用于数据的实际重新编码步骤:首先从(假定的)Windows-1252 到 UTF-8,然后从 ISO-8859-1 到 UTF-8 两次。iconv

那么我们该如何解决呢?好吧,我们只需要反向应用相同的步骤:

$ 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

好消息是这个过程应该是可逆的。坏消息是原始文本中的任何“ü”、“ì”、“Å”、“É”和“Ø”字母都可能被不可逆转地损坏,因为在 CP850 中用于编码这些字母的字节在 Windows 中是未定义的-1252。(如果幸运的话,它们可能已被解释为这些字节在 ISO-8859-1 中表示的相同C1 控制代码,在这种情况下,原则上应该可以进行反向转换。我还没有弄清楚如何不过,说服iconv他们这样做。)

于 2018-12-28T20:46:27.297 回答