使用Python3处理UTF-8文件中的编码错误



我正试图使用语料库来训练ML模型,但我遇到了一些编码错误,这些错误可能是由其他人对文件的转换/注释引起的。在vim中打开文件时,我可以直观地看到错误,但python在阅读时似乎没有注意到。语料库相当大,所以我需要找到一种方法让python检测它们,并希望找到一种纠正它们的方法。

这是在vim中看到的一条采样线。。。

# ::snt That<92>s what we<92>re with<85>You<92>re not sittin<92> there in a back alley and sayin<92> hey what do you say, five bucks?

<92>应该是撇号,并且<85>应该是3个点。还有许多其他值出现在其他行上。通过谷歌搜索,我认为最初的编码可能是CP1252,但目前Linux下的file命令将该文件列为UTF-8。我试过几种方法打开这个,但没有成功。。。

with open(fn) as f:返回

# ::snt Thats what were withYoure not sittin there in a back alley and sayin hey what do you say, five bucks?

这就是跳过那些标记并连接单词,这是一个问题。

with open(fn, encoding='CP1252') as f:返回

# ::snt ThatA's what weA're withA...YouA're not sittinA' there in a back alley and sayinA' hey what do you say, five bucks?

其在视觉上插入";A";那些奇怪的字符。

with io.open(fn, errors='strict')没有引起任何错误,读取字节流和解码也没有,所以不幸的是,在这一点上,我甚至无法检测到错误,更不用说对它们的正确性了。

有没有办法读取这个大文件并检测其中的编码错误。更好的是,有没有办法纠正它们?

使用您的答案中的原始数据,您得到了来自双重编码的mojibake。你需要双重解码才能正确翻译。

>>> s = b'# ::snt Thatxc2x92s what wexc2x92re withxc2x85Youxc2x92re not sittinxc2x92 there in a back alley and sayinxc2x92 hey what do you say, five bucks?n'
>>> s.decode('utf8').encode('latin1').decode('cp1252')
'# ::snt That’s what we’re with…You’re not sittin’ there in a back alley and sayin’ hey what do you say, five bucks?n'

数据实际上是UTF-8格式的,但在解码为Unicode时,错误的代码点是Windows-1252代码页的字节。.encode('latin1')将Unicode码点1:1转换回字节,由于latin1编码是Unicode的前256个码点,因此可以将其正确解码为Windows-1252。

这里有一个可行但不太优雅的解决方案。。。

# Read in file as a raw byte-string
fn  = 'bad_chars.txt'
with open(fn, 'rb') as f:
text = f.read()
print(text)
# Detect out of range 
has_bad = False
for c in text:
if c >= 128:
has_bad = True
print('Had bad:', has_bad)
# Fix offending characters
text = text.replace(b'xc2x92', b"x27")
text = text.replace(b'xc2x85', b"...")
text = text.decode('utf-8')
print(text)

它产生以下输出。。。

b'# ::snt Thatxc2x92s what wexc2x92re withxc2x85Youxc2x92re not sittinxc2x92 there in a back alley and sayinxc2x92 hey what do you say, five bucks?n'
Had bad: True
# ::snt That's what we're with...You're not sittin' there in a back alley and sayin' hey what do you say, five bucks?

缺点是,我需要找到有问题的字符,并编写一个replace命令才能正常工作。在..中的一个类似问题中找到了可能的替换代码表。有效地替换坏字符。

最新更新