Подтвердить что ты не робот

Как преобразовать формат файла из Unicode в ASCII с помощью Python?

Я использую сторонний инструмент, который выводит файл в формате Unicode. Однако я предпочитаю, чтобы это было в ASCII. У инструмента нет настроек для изменения формата файла.

Каков наилучший способ преобразования всего формата файла с помощью Python?

4b9b3361

Ответ 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'>