Как использовать unidecode в python (3.3)
я пытаюсь удалить все символы, отличные от ascii, из текстового документа. Я нашел пакет, который должен сделать именно это,https://pypi.python.org/pypi/Unidecode
он должен принять строку и преобразовать все символы, отличные от ascii, в ближайший символ ascii. Я использовал этот же модуль в perl достаточно легко, просто позвонив while (<input>) { $_ = unidecode($_); }
и это один прямой порт модуля perl, документация указывает, что он должен работать тот же.
я уверен, что это что-то простое, я просто не понимаю, достаточно о характере и кодирование файла, чтобы знать, в чем проблема. Мой исходный файл закодирован в UTF-8 (преобразован из UCS-2LE). Проблема может иметь больше общего с моим отсутствием знаний кодирования и обработки строк неправильно, чем модуль, надеюсь, кто-то может объяснить, почему. Я пробовал все, что знаю, без случайной вставки кода и поиска ошибок, которые я получаю без везения, так что далеко.
вот мой питон
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 = unidecode(str(line))
потом он будет писать в файл, но... не совсем так. rn'b'xefxbbxbf[ 2013.10.05 16:18:01 ] User_Name > .xe2x95x90xe2x95x90xe2x95x90xe2x95x90
он выписывает символы n, r и т. д. и unicode вместо их преобразования в что угодно.
если я преобразую строку в строку, как указано выше, и открою convertfile в байтовом режиме 'wb'
это дает ошибку TypeError: 'str' does not support the buffer interface
если я открою его в режиме байта, не объявляя его строкой 'wb'
и unidecode(line)
Я TypeError: ord() expected string length 1, but int found
опять ошибка.
1 ответов
на unidecode
модуль принимает unicode строковые значения и возвращает строка юникода в Python 3. Вместо этого вы даете ему двоичные данные. Декодируйте в unicode или откройте входной текстовый файл в textmode и Закодируйте результат в ASCII перед записью в файл или откройте выходной текстовый файл в текстовом режиме.
цитирую из документации модуля:
модуль экспортирует одну функцию, которая принимает объект Unicode (Python 2.икс) или строка (Python 3.x) и возвращает строку (это может быть закодировано в байты ASCII в Python 3.x)
выделено мной.
Это должно работать:
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)
это открывает inputfile в текстовом модусе (используя кодировку UTF8, которая, судя по вашей строке выборки, правильна) и записывает в текстовом модусе (кодировка в ASCII).
вам нужно явно указать кодировку файла, который вы открываете; если вы опустите используется кодировка текущей локали системы (результат locale.getpreferredencoding(False)
call), который обычно не будет правильным кодеком, если ваш код должен быть переносимым.