4

我正在清理 Europarl 的法语单语语料库(http://data.statmt.org/wmt19/translation-task/fr-de/monolingual/europarl-v7.fr.gz)。文件中的原始原始数据.gz(我使用下载的wget)。我想提取文本并查看它的外观,以便进一步处理语料库。

使用以下代码从中提取文本gzip,我获得了类为 的数据bytes

with gzip.open(file_path, 'rb') as f_in:
    print('type(f_in)=', type(f_in))
    text = f_in.read()
    print('type(text)=', type(text))

前几行的打印结果如下:

类型(f_in)=类'gzip.GzipFile'

类型(文本)=类'字节'

b'Reprise de la session\nJe d\xc3\xa9clare reprise la session du Parlement europ\xc3\xa9en qui avait \xc3\xa9t\xc3\xa9 interrompue le vendredi 17 d\xc3\xa9cembre dernier et je vous renouvelle tous mes vux en esp\xc3\xa9rant que vous avez pass\xc3\xa9 de bonnes vacances。\ncome vous avez pu le constater, le grand "bogue de l\'an 2000" ne s\'est pas produit。\n

我尝试使用以下代码解码utf8二进制数据:ascii

with gzip.open(file_path, 'rb') as f_in:
    print('type(f_in)=', type(f_in))
    text = f_in.read().decode('utf8')
    print('type(text)=', type(text))

它返回如下错误:

UnicodeEncodeError:“ascii”编解码器无法在位置 26 编码字符“\xe9”:序数不在范围内(128)

我也尝试使用codecsunicodedata包来打开文件,但它也返回了编码错误。

你能帮我解释一下我应该怎么做才能得到正确格式的法语文本,例如这样吗?

Reprise de la session\nJe déclare reprise la session du Parlement européen qui avait été interrompue le vendredi 17 月 17 日 dernier et je vous renouvelle tous mes vux en espérant que vous avez passé de bonnes vacances。\nComme vous avez pu le constater, le grand " bogue de l'an 2000" ne s'est pas produit。\n

非常感谢您的帮助!

4

2 回答 2

1

非常感谢您的帮助!我找到了一个简单的解决方案。我不确定它为什么会起作用,但我认为可能.txt以某种方式支持该格式?如果您知道该机制,那么了解将非常有帮助。

with gzip.open(file_path, 'rb') as f_in:
    text = f_in.read()

with open(os.path.join(out_dir, 'europarl.txt'), 'wb') as f_out:
    f_out.write(text)

当我在终端打印出文本文件时,它看起来像这样:

Reprise de la session Je déclare reprise la session du Parlement européen qui avait été interrompue le vendredi 12 月 17 日 dernier et je vous renouvelle tous mes vux en espérant que vous avez passé de bonnes vacances。Comme vous avez pu le constater, le grand "bogue de l'an 2000" ne s'est pas produit。En revanche, les citoyens d'un certain nombre de nos pay ont étévictimes de catastrophes naturelles qui ont vraiment été wrongs。Vous avez souhaité un débat à ce sujet dans les prochains jours, au cours de cette période de session。

于 2019-07-25T10:31:26.763 回答
1

发生 UnicodeEncodeError 是因为在打印时,Python 将字符串编码为字节,但在这种情况下,所使用的编码 - ASCII - 没有匹配 '\xe9' 的字符,因此引发了错误。

设置PYTHONIOENCODING环境变量会强制 Python 使用不同的编码 - 环境变量的值。UTF-8 编码可以编码任何字符,所以像这样调用程序可以解决这个问题:

PYTHONIOENCODING=UTF-8 python3  europarl_extractor.py

假设代码是这样的:

import gzip

if __name__ == '__main__':
    with gzip.open('europarl-v7.fr.gz', 'rb') as f_in:
        bs = f_in.read()
        txt = bs.decode('utf-8')
        print(txt[:100])

环境变量可以通过其他方式设置 - 通过export语句、 in.bashrc.profile

一个有趣的问题是为什么Python 试图将输出编码为 ASCII。我曾假设在 *nix 系统上,Python 本质上是查看$LANG环境变量来确定要使用的编码。但是在值$LANGis的情况下fr_FR.UTF-8,Python 使用 ASCII 作为输出编码。

通过查看模块的源代码locale和此FAQ,依次检查这些环境变量:

'LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE'

因此,可能是其中之一LC_ALLLC_CTYPE已设置为在您的环境中强制执行 ASCII 编码的值(您可以通过locale在终端中运行命令来检查;运行locale charmap也会告诉您编码本身)。

于 2019-07-26T17:31:55.813 回答