提问者:小点点

检测错误编码的UTF-8文本文件中的编码


我有一个编码问题。

我有数百万个文本文件需要为语言数据科学项目进行解析。每个文本文件都编码为UTF-8,但我刚刚发现其中一些源文件的编码不正确。

例如我有一个中文文本文件,编码为UTF-8,但文件中的文本如下所示:

Subject: »Ø¸´: ÎÒÉý¼¶µ½

当我使用Python检测此中文文本文件的编码时:

Chardet告诉我文件编码为UTF-8:

with open(path,'rb') as f:
    data = ""
    data = f.read()
    encoding=chardet.detect(data)['encoding']

UnicodeDammit还告诉我该文件编码为UTF-8:

with open(path,'rb') as f:
    data = ""
    data = f.read()
    encoding= UnicodeDammit(data).original_encoding

同时,我知道这不是UTF-8,而是GB2312中文编码。如果我在记事本中打开这个文件,它也会被检测为UTF-8,所有汉字都会显示为乱码。只有当我手动将记事本中的编码切换到GB2312时,我才能获得正确的文本:

Subject: 禄脴赂麓: 脦脪脡媒录露碌陆

我有很多这样的文件,用各种语言。

有没有一种方法可以检测这些编码不良的UTF-8文件中的编码?

示例文本文件可在此处下载:https://gofile.io/d/qMcgkt


共2个答案

匿名用户

最后,我终于明白了。使用CharsetNormalizerMatches似乎可以正常检测编码。无论如何,这就是我实现它的方式,它就像一个魔咒,正确地检测到所讨论的文件的gb18030编码:

from charset_normalizer import CharsetNormalizerMatches as CnM
encoding = CnM.from_path(path).best().first().encoding

注意:有人向我暗示了答案,他建议使用CharsetNormalizerMatches,但后来在这里删除了他的帖子。太糟糕了,我很乐意把这归功于他/她。

匿名用户

您无法获得链接示例的明确编码。txt文件连接了两种不同的编码:

path = r'D:\Downloads\example.txt'
with open(path,'rb') as f:
    data = f.read()

# double mojibake
print( data[:37].decode('utf-8').encode('latin1').decode('gb2312') )

# Chinese
print( data[37:].decode('gb2312') )

结果粘贴到谷歌翻译给出

Subject: Re: I upgraded to

The orange version of the orange version, should be corrected

不幸的是,SO认为结果中的中文文本是垃圾邮件,所以我无法将其嵌入此处…

正文不能包含“”。

这似乎是垃圾邮件。如果您认为我们犯了错误,请在meta中发表帖子。

编辑:print(data[: 37]. decode('gb18030'))返回

Subject: 禄脴赂麓: 脦脪脡媒录露碌陆

Google Translate然后给出主题:Lulululu:lululululu Lulu,作为后一个字符串的英语等价物
无论如何,上述主题:Re:I Upgrade to(或Mark Tolonen建议的Re:I Upgration to)看起来比这更有意义…