我正在尝试从文本文档中删除所有非ASCII字符。我找到了一个应该做到这一点的软件包https://pypi.python.org/pypi/Unidecode
它应该接受一个字符串,并将所有非ASCII字符转换为最接近的可用ASCII字符。我仅通过调用while (<input>) { $_ = unidecode($_); }
就很容易地在perl中使用了这个模块,而这个模块是perl模块的直接端口,文档表明它应该工作相同。
我敢肯定这很简单,我只是对字符和文件编码了解得不够多,所以不知道问题出在哪里。我的原始文件以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();
如果我没有以字节模式(
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声明为字符串
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等和Unicode字符,而不是将它们转换为任何字符。如果我如上所述将行转换为字符串,并以字节模式
'wb'
打开convertfile,则会出现错误TypeError: 'str' does not support the buffer interface
如果我在不声明字符串
'wb'
和unidecode(line)
的情况下以字节模式打开它,则我再次收到TypeError: ord() expected string length 1, but int found
错误。 最佳答案
unidecode
模块接受unicode字符串值,并在Python 3中返回一个unicode字符串。您改为为其提供二进制数据。解码为unicode或以textmode打开输入文本文件,然后将结果编码为ASCII,然后再将其写入文件,或以text模式打开输出文本文件。
引用模块文档:
强调我的。
这应该工作:
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)
调用的结果),如果您的代码需要可移植,则通常不是正确的编解码器。关于python - 如何在python(3.3)中使用unidecode,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19771751/