У меня есть строка Unicode в Python, и я хотел бы удалить все акценты (диакритические знаки).
Я нашел в Интернете элегантный способ сделать это на Java:
- преобразовать строку Unicode в ее длинную нормализованную форму (с отдельным символом для букв и диакритических знаков)
- удалить все символы, у которых тип Unicode "диакритический".
Нужно ли устанавливать такую библиотеку, как pyICU, или это возможно только с помощью стандартной библиотеки python? А как насчет Python 3?
Важное примечание: я хотел бы избежать кода с явным отображением символов с акцентом на их не акцентированный аналог.
python
python-3.x
unicode
python-2.x
diacritics
MiniQuark
источник
источник
unidecode
заменяется°
наdeg
. Это больше, чем просто удаление акцентов.Как насчет этого:
Это работает и на греческих буквах:
Категория символов «Mn» означает
Nonspacing_Mark
, что аналогично unicodedata.combining в ответ MiniQuark в (я не думаю о unicodedata.combining, но это, вероятно, лучшее решение, потому что это более явным).И имейте в виду, что эти манипуляции могут существенно изменить смысл текста. Акценты, умлауты и т. Д. Не являются «украшением».
источник
unicodedata.name
, либо разбить таблицу на части и использовать похожий стол, который вам в любом случае понадобится для греческих букв (Α это просто «ГРЕЧЕСКАЯ КАПИТАЛЬНАЯ ПИСЬМА АЛЬФА»).A
. Если не хотите, не делайте этого, но в обоих случаях вы заменяете латиницу (почти) аналогично.ß
в asciiss
в примере. Я бы все еще использовал,unidecode
чтобы избежать несчастных случаев.Я только что нашел этот ответ в Интернете:
Он отлично работает (например, для французского), но я думаю, что второй шаг (удаление акцентов) мог бы быть лучше обработан, чем удаление символов не-ASCII, потому что это не получится для некоторых языков (например, греческого). Лучшим решением, вероятно, было бы явное удаление символов Юникода, которые помечены как диакритические.
Изменить : это делает трюк:
unicodedata.combining(c)
вернет true, если символc
может быть объединен с предыдущим символом, то есть главным образом, если это диакритический знак.Редактирование 2 :
remove_accents
ожидает строку в юникоде , а не строку байта. Если у вас есть строка байтов, то вы должны декодировать ее в строку Unicode, например:источник
nkfd_form = unicodedata.normalize('NFKD', unicode(input_str, 'utf8'))
, 'utf8'
это «сеть безопасности», необходимая, если вы тестируете ввод в терминале (который по умолчанию не использует юникод). Но обычно вам не нужно добавлять его, так как если вы удаляете акценты, то,input_str
скорее всего, уже будет utf8. Впрочем, быть в безопасности не вредно.remove_accents
вместо обычной строки (u «é» вместо «é»). Вы передали обычную строкуremove_accents
, поэтому при попытке преобразовать вашу строку в строку Unicodeascii
была использована кодировка по умолчанию . Эта кодировка не поддерживает ни одного байта, значение которого> 127. Когда вы ввели «é» в своей оболочке, ваша ОС закодировала это, вероятно, с помощью UTF-8 или некоторой кодировки Windows Code Page, и это включало байты> 127. Я изменю свою функцию, чтобы убрать преобразование в юникод: оно будет бомбить более четко, если пропущена не-юникодная строка.На самом деле я работаю над проектами, совместимыми с Python 2.6, 2.7 и 3.4, и мне нужно создавать идентификаторы из бесплатных записей пользователя.
Благодаря вам, я создал эту функцию, которая творит чудеса.
результат:
источник
text = unicode(text, 'utf-8')
. Обходной путь для этого должен был добавитьexcept TypeError: pass
Это обрабатывает не только акценты, но и «удары» (как в ø и т. Д.):
Это самый изящный способ, которым я могу придумать (и он был упомянут Алексисом в комментарии на этой странице), хотя я не думаю, что это действительно очень элегантно. На самом деле, это скорее хак, как отмечалось в комментариях, поскольку имена в Юникоде - на самом деле просто имена, они не дают гарантии того, что они согласованы или что-то в этом роде.
Есть еще специальные буквы, которые не обрабатываются этим, такие как перевернутые и перевернутые буквы, так как их имя в юникоде не содержит «WITH». Это зависит от того, что вы хотите сделать в любом случае. Иногда мне требовалось удаление акцента для достижения порядка сортировки словаря.
РЕДАКТИРОВАТЬ ПРИМЕЧАНИЕ:
Включенные предложения из комментариев (обработка ошибок поиска, код Python-3).
источник
unicode
вызов функции с Python 3? Я думаю, что более жесткое регулярное выражение вместо этогоfind
позволит избежать всех проблем, упомянутых в комментарии выше, а также, памятование поможет производительности, когда это критический путь кода.unicode
напечатанная больше не ассигновать в Python 3. В любом случае, в моем опыте нет универсального, элегантного решения этой проблемы. В зависимости от приложения любой подход имеет свои плюсы и минусы. Качественные инструментыunidecode
, основанные на ручных таблицах. Некоторые ресурсы (таблицы, алгоритмы) предоставляются Unicode, например. для сопоставления.В ответ на ответ @ MiniQuark:
Я пытался прочитать в CSV-файл, который был наполовину французским (с акцентами), а также некоторые строки, которые в конечном итоге стали бы целыми числами и числами с плавающей точкой. В качестве теста я создал
test.txt
файл, который выглядел так:Мне пришлось включить строки
2
и3
заставить его работать (что я нашел в билете на python), а также включить комментарий @ Jabba:Результат:
(Примечание: я нахожусь на Mac OS X 10.8.4 и использую Python 2.7.3)
источник
remove_accents
был предназначен для удаления акцентов из строки Unicode. В случае, если ему передана строка байтов, она пытается преобразовать ее в строку Unicode с помощьюunicode(input_str)
. Это использует кодировку по умолчанию Python, которая "ascii". Поскольку ваш файл закодирован с помощью UTF-8, это не получится. Строки 2 и 3 изменяют кодировку Python по умолчанию на UTF-8, так что тогда это работает, как вы узнали. Другой вариант - передатьremove_accents
строку в юникоде: удалить строки 2 и 3, а в последней строке заменитьelement
наelement.decode("utf-8")
. Я проверял: это работает. Я уточню свой ответ, чтобы прояснить ситуацию.iso-8859-1
, но я, к сожалению, не могу работать с этой функцией!)reload(sys); sys.setdefaultencoding("utf-8")
сомнительный хак, иногда рекомендуемый для систем Windows; см. stackoverflow.com/questions/28657010/… для получения подробной информации.gensim.utils.deaccent (текст) от Gensim - тема моделирования для людей :
Другое решение - unidecode .
Обратите внимание, что предлагаемое решение с unicodedata обычно удаляет акценты только в некотором символе (например, оно превращается
'ł'
в''
, а не в'l'
).источник
deaccent
все равно даетł
вместоl
.NumPy
иSciPy
удалять акценты.Некоторые языки объединяют диакритические знаки в виде букв языка и диакритических знаков акцента для определения акцента.
Я думаю, что более безопасно явно указать, какие диалектики вы хотите удалить:
источник