在一个可能由于质量低下和用户缺乏兴趣而可能被关闭的问题中,粘贴了以下文本,显然不正确,因为出现了“奇怪”字符而不是重音元音或 eñes:
用铁棒)有太多的冗余,只有论证就足够了。我能说的是我的名字。我的名字是”
显然,用户收到了一些带有未知编码的文本,在使用另一种(也是未知的)编码的编辑器中打开它,并复制并粘贴了该编辑器向他显示的内容到问题中。
可能您的操作员,无论您的编辑器使用何种编码,都将文本转换为 Unicode 以便将其保存到剪贴板,因此最终粘贴到问题中的版本是这些 Unicode 字符的 UTF-8 表示。
问题是如何确定数据的原始编码?为了恢复文本的外观。
我的解决方案使用 Python 3 和一些侦探工作。我们首先将从问题复制的文本分配给一个变量:
使用 Python,有一些库可以自动检测字节序列的编码,例如 module
chardet
。但是,这种类型的解决方案在这里不起作用,因为我们无法访问原始字节序列,而是访问在 StackOverflow 中粘贴文本的结果,并将结果转换为 UTF-8。事实上,
chardet.detect()
它需要一个字节字符串作为参数,但在这种情况下,我们只有一个字符串,我们必须将其传递给字节,例如texto_mal.encode(...)
,并且我们必须指定一个编码,这是我们想发现什么。那该怎么办?
我们可以使用一些启发式方法,依赖于文本是西班牙语的事实,并且我们大部分时间都可以阅读其内容。事实上,我们可以推断它
‡
代表字母á
,它’
代表í
,它可能ƒ
是É
等等。让我们暂时只关注其中一个角色。然后我们可以将问题重新表述为:
为了回答这个问题,我尝试在 python 支持的所有可能的编码中对符号
"‡"
进行编码,以获得一个字节(或字节序列),然后我继续使用每种可能的编码再次对其进行编码,看看哪个是结果是一个"á"
(当然,忽略所有产生编码错误的那些):结果是一组 44 对编码,例如,其中一个(我选择它是因为它似乎最有可能)是
cp1252 mac_roman
.这意味着用户(总是假设性地)收到了一个具有编码的文本文件
mac_roman
(在较旧的Mac上使用),但使用使用该编码的编辑器(可能是Windowscp1252
记事本)打开它,因此看到了所有那些奇怪的字符。在 Stack Overflow 上复制和粘贴它们时,它们被接收为 Unicode(“utf-8”),使问题进一步复杂化,因为不再可能看到原始字节。因此,用 编码用户给出的文本并用
cp1252
再次解码mac_roman
,它看起来已经可读: