# -*- encoding: utf-8 -*-
import unicodedata
def shoehorn_unicode_into_ascii(s):
return unicodedata.normalize('NFKD', s).encode('ascii','ignore')
if __name__=='__main__':
s = u"éèêàùçÇ"
print(shoehorn_unicode_into_ascii(s))
# eeeaucC
Обратите внимание, как @Mark Tolonen любезно указывает, приведенный выше метод удаляет некоторые символы, такие как
ß ' «». Если приведенный выше код усекает символы, которые вы хотите перевести, то вам, возможно, придется использовать строковый метод translate
, чтобы вручную исправить эти проблемы. Другой вариант - использовать unidecode (см. J.F. Себастьян ).
Если у вас есть большая строка в Юникоде, использование метода translate
будет очень
гораздо быстрее, чем при использовании метода replace
.
Редактировать: unidecode
имеет более полное отображение кодовых точек юникода в ascii.
Однако unidecode.unidecode
циклически перебирает строку за символом (в цикле Python), что медленнее, чем при использовании метода translate
.
Следующая вспомогательная функция использует файлы данных unidecode
и метод translate
для достижения лучшей скорости, особенно для длинных строк.
В моих тестах с текстовыми файлами объемом 1-6 МБ использование ascii_map
примерно в 4-6 раз быстрее, чем unidecode.unidecode
.
# -*- coding: utf-8 -*-
import unidecode
def ascii_map():
data={}
for num in range(256):
h=num
filename='x{num:02x}'.format(num=num)
try:
mod = __import__('unidecode.'+filename,
fromlist=True)
except ImportError:
pass
else:
for l,val in enumerate(mod.data):
i=h<<8
i+=l
if i >= 0x80:
data[i]=unicode(val)
return data
if __name__=='__main__':
s = u"éèêàùçÇ"
print(s.translate(ascii_map()))
# eeeaucC
Edit2: Rhubarb, если # -*- encoding: utf-8 -*-
вызывает SyntaxError, попробуйте
# -*- encoding: cp1252 -*-
. Какую кодировку объявить, зависит от того, какую кодировку ваш текстовый редактор использует для сохранения файла. Linux склонен использовать utf-8, и (кажется, возможно) Windows склонна к cp1252.