Как преобразовать формат файла из Unicode в ASCII с помощью Python?
Я использую сторонний инструмент, который выводит файл в формате Unicode. Однако я предпочитаю, чтобы это было в ASCII. У инструмента нет настроек для изменения формата файла.
Каков наилучший способ преобразования всего формата файла с помощью Python?
Ответы
Ответ 1
Вы можете легко преобразовать файл, просто используя функцию unicode
, но вы столкнетесь с проблемами с символами Unicode без прямого эквивалента ASCII.
Этот блог рекомендует использовать модуль unicodedata
, который, по-видимому, заботится о грубо преобразовании символов без прямых соответствующих значений ASCII, например
>>> title = u"Klüft skräms inför på fédéral électoral große"
обычно преобразуется в
Klft skrms infr p fdral lectoral groe
что довольно неправильно. Однако, используя модуль unicodedata
, результат может быть намного ближе к исходному тексту:
>>> import unicodedata
>>> unicodedata.normalize('NFKD', title).encode('ascii','ignore')
'Kluft skrams infor pa federal electoral groe'
Ответ 2
Я думаю, что это более глубокая проблема, чем вы понимаете. Простое изменение файла из Unicode в ASCII легко, однако, получение всех символов Unicode для перевода в разумные копии ASCII (многие буквы не доступны в обоих кодировках) - это другое.
Этот учебник по юникоду Python может дать вам лучшее представление о том, что происходит с строками Unicode, которые переведены в ASCII: http://www.reportlab.com/i18n/python_unicode_tutorial.html p >
Здесь полезная цитата с сайта:
Python 1.6 также получает "unicode" встроенная функция, с помощью которой вы можете укажите кодировку:
> >>> unicode('hello') u'hello'
> >>> unicode('hello', 'ascii') u'hello'
> >>> unicode('hello', 'iso-8859-1') u'hello'
> >>>
Все три из них возвращают одинаковые потому что символы в 'Hello' являются общими для всех трех кодировок.
Теперь позвольте закодировать что-нибудь с Европейский акцент, который находится вне ASCII. То, что вы видите на консоли, может зависит от вашей операционной системы локали; Windows позволяет мне вводить ISO-Latin-1.
> >>> a = unicode('André','latin-1')
> >>> a u'Andr\202'
Если вы не можете набрать острую букву e, вы можете ввести строку "Andr\202", что недвусмысленно.
Unicode поддерживает все общие таких операций, как итерация и расщепление. Мы не будем их преодолевать здесь.
Ответ 3
Кстати, это команда linux iconv
для выполнения этого вида работы.
iconv -f utf8 -t ascii <input.txt >output.txt
Ответ 4
Вот так:
uc = open(filename).read().decode('utf8')
ascii = uc.decode('ascii')
Обратите внимание, что это будет сбой с исключением UnicodeDecodeError
, если есть какие-либо символы, которые не могут быть преобразованы в ASCII.
EDIT: как только указывал Пит Карл, между Unicode и ASCII нет однозначного отображения. Поэтому некоторые символы просто не могут быть преобразованы в режиме сохранения информации. Более того, стандартный ASCII является более или менее подмножеством UTF-8, поэтому вам даже не нужно делать какое-либо декодирование.
Ответ 5
Вот какой простой (и глупый) код для кодирования. Я предполагаю (но не должен), чтобы входной файл находился в UTF-16 (Windows называет это просто "Unicode" ).
input_codec = 'UTF-16'
output_codec = 'ASCII'
unicode_file = open('filename')
unicode_data = unicode_file.read().decode(input_codec)
ascii_file = open('new filename', 'w')
ascii_file.write(unicode_data.write(unicode_data.encode(output_codec)))
Обратите внимание, что это не будет работать, если в файле Unicode есть какие-либо символы, которые не являются также символами ASCII. Вы можете сделать следующее, чтобы включить нераспознанные символы в '?' S:
ascii_file.write(unicode_data.write(unicode_data.encode(output_codec, 'replace')))
Зайдите документы для более простых выборов. Если вам нужно сделать что-нибудь более сложное, вы можете проверить UNICODE Hammer в Поваренной книге Python.
Ответ 6
Для моей проблемы, когда я просто хотел пропустить символы Non-ascii и просто выводить только ascii-выход, решение ниже работало очень хорошо:
import unicodedata
input = open(filename).read().decode('UTF-16')
output = unicodedata.normalize('NFKD', input).encode('ASCII', 'ignore')
Ответ 7
Важно отметить, что формат файлов Unicode отсутствует. Unicode может быть закодирован в байтах несколькими различными способами. Чаще всего UTF-8 или UTF-16. Вам нужно будет узнать, какой из них выводит ваш сторонний инструмент. Как только вы это знаете, преобразование между различными кодировками довольно просто:
in_file = open("myfile.txt", "rb")
out_file = open("mynewfile.txt", "wb")
in_byte_string = in_file.read()
unicode_string = bytestring.decode('UTF-16')
out_byte_string = unicode_string.encode('ASCII')
out_file.write(out_byte_string)
out_file.close()
Как отмечено в других ответах, вы, вероятно, захотите предоставить обработчик ошибок для метода кодирования. Использование "replace" в качестве обработчика ошибок прост, но будет искажать ваш текст, если он содержит символы, которые не могут быть представлены в ASCII.
Ответ 8
Как отмечали другие плакаты, ASCII является подмножеством юникода.
Однако если вы:
- есть устаревшее приложение
- вы не контролируете код для этого приложения
- вы уверены, что ваш вход попадает в подмножество ASCII
Затем пример ниже показывает, как это сделать:
mystring = u'bar'
type(mystring)
<type 'unicode'>
myasciistring = (mystring.encode('ASCII'))
type(myasciistring)
<type 'str'>