如何在 Python 中使用 unidecode

2024-07-12 10:26:27 浏览数 (3)

在 Python 中使用 unidecode 库可以将 Unicode 文本转换为 ASCII。这对于需要处理非英文字符的文本并且希望保持可读性时非常有用。以下是如何在 Python 中使用 unidecode 库的示例和步骤:

1、问题背景

我正在尝试从文本文件中删除所有非 ASCII 字符。我找到一个程序包应该可以做到这一点,https://pypi.python.org/pypi/Unidecode。它应该接受一个字符串并将所有非 ASCII 字符转换为最接近的可用 ASCII 字符。我在 perl 中很容易地使用了这个模块,只需调用 while (<input>) { $_ = unidecode($_); },这个模块是对 perl 模块的直接移植,文档表明它应该以相同的方式工作。 我确信这是一个简单的问题,我只是对字符和文件编码了解不够,不知道问题出在哪里。我的原始文件编码为 UTF-8(从 UCS-2LE 转换而来)。问题可能更多地与我缺乏编码知识和错误处理字符串有关,而不是模块,但希望有人可以解释一下原因。到目前为止,我已经尝试了我所知道的一切,没有随机插入代码并搜索我遇到的错误。

以下是我的 Python 代码:

代码语言:javascript复制
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();

如果我不在字节模式下打开原始文件(origfile = open('file.txt','r')),那么我会收到错误 UnicodeDecodeError: 'charmap' codec can't decode byte 0x90 in position 1563: character maps to <undefined> 来自 for line in origfile: line.。 如果我确实在字节模式 'rb' 中打开它,那么我收到 TypeError: ord() expected string length 1, but int found 来自 line = unidecode(line)。 如果我将 line 声明为字符串 line = unidecode(str(line)) 那么它会写入文件,但...不正确。rn'b'xefxbbxbf[ 2013.10.05 16:18:01 ] User_Name > .xe2x95x90xe2x95x90xe2x95x90xe2x95x90,它正在写出 n、r 等和 unicode 字符而不是将它们转换为任何东西。 如果我像上面一样将这行转换为字符串,并在字节模式 'wb' 中打开转换文件,那么会给出错误 TypeError: 'str' does not support the buffer interface。 如果我不声明它为字符串 'wb' 并 unidecode(line) 在字节模式下打开它,那么我再次收到 TypeError: ord() expected string length 1, but int found 错误。

2、解决方案

unidecode 模块接受 unicode 字符串值并返回 Python 3 中的 unicode 字符串。你给它的是二进制数据。解码成 unicode 或在文本模式下打开输入文本文件,并在写入文件之前将结果编码成 ASCII,或在文本模式下打开输出文本文件。 引用模块文档:

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

重点是我的。

以下应有效:

代码语言:javascript复制
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)

这以文本模式打开输入文件(使用 UTF8 编码,根据示例行判断,这是正确的)并以文本模式写入(编码为 ASCII)。 你确实需要显式指定要打开的文件的编码;如果你省略了编码,那么使用当前系统区域设置(locale.getpreferredencoding(False) 调用结果),如果你的代码需要是可移植的,那么这通常不是正确的编解码器。

其实说白了通过使用 unidecode,我们可以有效地处理包含多种语言字符的文本,使其更易于处理和分析,同时保持文本的可读性。

0 人点赞