Заменить специальные символы на эквивалент ASCII

python unicode

13485 просмотра

6 ответа

Есть ли библиотека, которая может заменить специальные символы на эквиваленты ASCII, например:

"Cześć"

чтобы:

"Czesc"

Я могу конечно создать карту:

{'ś':'s', 'ć': 'c'}

и использовать некоторую функцию замены. Но я не хочу жестко закодировать все эквиваленты в моей программе, если есть какая-то функция, которая уже делает это.

Автор: Tomasz Wysocki Источник Размещён: 12.11.2019 09:39

Ответы (6)


33 плюса

Решение
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import unicodedata
text = u'Cześć'
print unicodedata.normalize('NFD', text).encode('ascii', 'ignore')
Автор: nosklo Размещён: 07.07.2010 12:19

15 плюса

Вы можете получить большую часть пути, выполнив:

import unicodedata

def strip_accents(text):
    return ''.join(c for c in unicodedata.normalize('NFKD', text) if unicodedata.category(c) != 'Mn')

К сожалению, существуют акцентированные латинские буквы, которые не могут быть разложены на ASCII-буквы + комбинирующие знаки. Вам придется обращаться с ними вручную. Они включают:

  • Æ → AE
  • Ð → D
  • Ø → O
  • TH → TH
  • ß → сс
  • æ → ае
  • ð → d
  • ø → o
  • th → й
  • Œ → OE
  • œ → oe
  • ƒ → f
Автор: dan04 Размещён: 12.07.2010 06:10

4 плюса

Я сделал это так:

POLISH_CHARACTERS = {
    50309:'a',50311:'c',50329:'e',50562:'l',50564:'n',50099:'o',50587:'s',50618:'z',50620:'z',
    50308:'A',50310:'C',50328:'E',50561:'L',50563:'N',50067:'O',50586:'S',50617:'Z',50619:'Z',}

def encodePL(text):
    nrmtxt = unicodedata.normalize('NFC',text)
    i = 0
    ret_str = []
    while i < len(nrmtxt):
        if ord(text[i])>128: # non ASCII character
            fbyte = ord(text[i])
            sbyte = ord(text[i+1])
            lkey = (fbyte << 8) + sbyte
            ret_str.append(POLISH_CHARACTERS.get(lkey))
            i = i+1
        else: # pure ASCII character
            ret_str.append(text[i])
        i = i+1
    return ''.join(ret_str)

при исполнении:

encodePL(u'ąćęłńóśźż ĄĆĘŁŃÓŚŹŻ')

он будет производить вывод так:

u'acelnoszz ACELNOSZZ'

Это прекрасно работает для меня -; D

Автор: Grzegorz Skrzypczak Размещён: 06.04.2012 01:43

3 плюса

Попробуйте транс- пакет. Выглядит очень перспективно. Поддерживает польский.

Автор: Marcin Wojnarski Размещён: 13.03.2012 11:40

1 плюс

Уловка unicodedata.normalize лучше всего описать как половину асси. Вот надежный подход, который включает в себя карту для букв без разложения. Обратите внимание на дополнительные записи карты в комментариях.

Автор: John Machin Размещён: 12.07.2010 07:13

0 плюса

Unidecode пакета работал лучше всего для меня:

from unidecode import unidecode
text = "Björn, Łukasz and Σωκράτης."
print(unidecode(text))
# ==> Bjorn, Lukasz and Sokrates.

Вам может понадобиться установить пакет:

pip install unidecode

Вышеупомянутое решение проще и надежнее, чем кодирование (и декодирование) выходных данных unicodedata.normalize(), как предлагают другие ответы.

ret = unicodedata.normalize('NFKD', text).encode('ascii', 'ignore')
print(ret)
# ==> b'Bjorn, ukasz and .'
# Besides not supporting all characters, the returned value is a
# bytes object in python3. To yield a str type:
ret = ret.decode("utf8") # (not required in python2)
Автор: normanius Размещён: 01.11.2019 07:31
Вопросы из категории :
32x32