





Я думаю, это более серьезная проблема, чем вы думаете. Просто изменить файл из Unicode в ASCII легко, однако получить перевод всех символов Unicode в разумные эквиваленты ASCII (многие буквы недоступны в обеих кодировках) - другое.
Этот учебник Python Unicode может дать вам лучшее представление о том, что происходит со строками Unicode, которые переведены в ASCII: http://www.reportlab.com/i18n/python_unicode_tutorial.html
Вот полезная цитата с сайта:
Python 1.6 also gets a "unicode" built-in function, to which you can specify the encoding:
> >>> unicode('hello') u'hello'
> >>> unicode('hello', 'ascii') u'hello'
> >>> unicode('hello', 'iso-8859-1') u'hello'
> >>>
All three of these return the same thing, since the characters in 'Hello' are common to all three encodings.
Now let's encode something with a European accent, which is outside of ASCII. What you see at a console may depend on your operating system locale; Windows lets me type in ISO-Latin-1.
> >>> a = unicode('André','latin-1')
> >>> a u'Andr2'
If you can't type an acute letter e, you can enter the string 'Andr2', which is unambiguous.
Unicode supports all the common operations such as iteration and splitting. We won't run over them here.
@ Рэй Вега: Это ты сейчас знаешь. Предполагать, что данные Unicode будут содержать только символы ASCII, является ошибкой и потенциальной ошибкой.
Нравится:
uc = open(filename).read().decode('utf8')
ascii = uc.decode('ascii')
Однако обратите внимание, что это будет провал с исключением UnicodeDecodeError, если есть какие-либо символы, которые не могут быть преобразованы в ASCII.
Обновлено: Как только что указал Пит Карл, нет однозначного сопоставления из Unicode в ASCII. Поэтому некоторые символы просто невозможно преобразовать таким образом, чтобы сохранить информацию. Более того, стандартный ASCII является более или менее подмножеством UTF-8, поэтому вам даже не нужно делать какое-либо декодирование.
Вы можете достаточно легко преобразовать файл, просто используя функцию 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'
Это довольно хорошо, за исключением того, что (как уже отмечалось) в нем не хватает нескольких символов. Для Latin-1 вам нужно использовать специальный регистр Æ, Ð, Ø, Þ, æ, ð, ø, ß и þ.
Об этом сообщил Фредрик Лунд с простым сценарием для создания поверх unicodedata для замены в особых случаях: effbot.org/zone/unicode-convert.htm
Вот простой (и глупый) код для перевода кодировки. Я предполагаю (но вы не должны), что входной файл находится в 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. Чтобы превратить нераспознанные символы в символы "?", Можно сделать следующее:
ascii_file.write(unicode_data.write(unicode_data.encode(output_codec, 'replace')))
Проверьте документы для более простого выбора. Если вам нужно сделать что-то более сложное, вы можете проверить Молот UNICODE в Кулинарной книге Python.
Важно отметить, что формата файлов 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.
Как отмечали другие плакаты, ASCII - это подмножество юникода.
Однако если вы:
Затем в приведенном ниже примере показано, как это сделать:
mystring = u'bar'
type(mystring)
<type 'unicode'>
myasciistring = (mystring.encode('ASCII'))
type(myasciistring)
<type 'str'>
Для моей проблемы, когда я просто хотел пропустить символы, отличные от ascii, и просто выводить только вывод ascii, приведенное ниже решение сработало очень хорошо:
import unicodedata
input = open(filename).read().decode('UTF-16')
output = unicodedata.normalize('NFKD', input).encode('ASCII', 'ignore')
Между прочим, это Linux-команда iconv для выполнения такой работы.
iconv -f utf8 -t ascii <input.txt >output.txt
Спасибо, что указали на потенциальные проблемы. Однако я не рискую иметь неконвертируемые символы Юникода в содержимом выходного файла. Он просто выводит схему SQL внутренней базы данных и не содержит никаких необычных символов, то есть за пределами ASCII.