如何在python中使用unidecode(3.3)

Bea*_*ing 9 python unicode encoding

我正在尝试从文本文档中删除所有非ascii字符.我找到了一个应该这样做的软件包,https://pypi.python.org/pypi/Unidecode

它应该接受一个字符串并将所有非ascii字符转换为最接近的ascii字符.我只是通过调用就可以很容易地在perl中使用这个相同的模块,这个模块是perl模块while (<input>) { $_ = unidecode($_); }的直接端口,文档表明它应该工作相同.

我确信这很简单,我对字符和文件编码了解不足以了解问题所在.我的origfile以UTF-8编码(从UCS-2LE转换).问题可能与我缺乏编码知识和处理字符串错误有关,而不是模块,希望有人可以解释为什么.我已经尝试了我所知道的一切,而不是随意插入代码并搜索我到目前为止没有运气的错误.

这是我的python

from unidecode import unidecode

def toascii():
    origfile = open(r'C:\log.convert', 'rb')
    convertfile = open(r'C:\log.toascii', 'wb')

    for line in origfile:
        line = unidecode(line)
        convertfile.write(line)

    origfile.close()
    convertfile.close()

toascii();
Run Code Online (Sandbox Code Playgroud)

如果我没有在字节模式(origfile = open('file.txt','r')中打开原始文件,那么我UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 1563: character maps to <undefined>从该for line in origfile:行得到一个错误.

如果我在字节模式下打开它,'rb'我就会TypeError: ord() expected string length 1, but int found从该line = unidecode(line)行开始.

如果我将行声明为字符串,line = unidecode(str(line))那么它将写入文件,但是......不正确.\r\n'b'\xef\xbb\xbf[ 2013.10.05 16:18:01 ] User_Name > .\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\它正在写出\n,\ r \n等和unicode字符,而不是将它们转换为任何东西.

如果我将行转换为如上所述的字符串,并在字节模式下打开convertfile 'wb'它会给出错误TypeError: 'str' does not support the buffer interface

如果我在字节模式下打开未声明的字符串'wb'unidecode(line)然后我得到了TypeError: ord() expected string length 1, but int found一次错误.

Mar*_*ers 9

unidecode模块接受unicode字符串值并在Python 3中返回一个unicode字符串.您将为其提供二进制数据.解码为unicode或在textmode中打开输入文本文件,并在将结果写入文件之前将结果编码为ASCII,或者以文本模式打开输出文本文件.

引用模块文档:

该模块导出一个函数,该函数接受Unicode对象(Python 2.x)或字符串(Python 3.x)并返回一个字符串(可以在Python 3.x中编码为ASCII字节)

强调我的.

这应该工作:

def toascii():
    with open(r'C:\log.convert', 'r', encoding='utf8') as origfile, open(r'C:\log.toascii', 'w', encoding='ascii') as convertfile:
        for line in origfile:
            line = unidecode(line)
            convertfile.write(line)
Run Code Online (Sandbox Code Playgroud)

这将打开文本模式的输入文件(使用UTF8编码,由您的采样行判断是正确的)并以文本模式(编码为ASCII)写入.

您需要明确指定要打开的文件的编码; 如果省略编码,则使用当前系统区域设置(locale.getpreferredencoding(False)调用的结果),如果您的代码需要可移植,通常不会是正确的编解码器.

  • 对于任何想知道并阅读本文的人来说,讨论仍在继续,根本问题最终是 python 3 默认情况下不会在 utf8 中打开文件。原始文件必须以 utf8 编码显式打开,转换后的文件必须以 ascii 编码打开。谢谢马丁。 (2认同)