Onde está o banco de dados “melhor ASCII para este Unicode” do Python? [fechadas]

86

Tenho alguns textos que usam pontuação Unicode, como aspas duplas à esquerda, aspas simples à direita para apóstrofo e assim por diante, e preciso disso em ASCII. O Python tem um banco de dados desses caracteres com substitutos ASCII óbvios para que eu possa fazer melhor do que transformá-los todos em "?" ?

joeforker
fonte
2
As pessoas que acharem isso podem estar interessadas em Qual é a melhor maneira de remover acentos em uma string Unicode Python?
Martin Thoma,

Respostas:

90

Unidecode parece uma solução completa. Ele converte aspas extravagantes em aspas ascii, caracteres latinos acentuados em não acentuados e até tenta a transliteração para lidar com caracteres que não têm equivalentes ASCII. Dessa forma, seus usuários não precisam ver muitos? quando você tinha que passar o texto por um sistema ascii de 7 bits legado.

>>> from unidecode import unidecode
>>> print unidecode(u"\u5317\u4EB0")
Bei Jing 

http://www.tablix.org/~avian/blog/archives/2009/01/unicode_transliteration_in_python/

joeforker
fonte
3
Hm .. tremas alemães são convertidos para seu caractere base em vez de, por exemplo, ö = oe, ä = ae, etc.
ThiefMaster
4
@ThiefMaster esses equivalentes são verdadeiros em todos os idiomas? Talvez o Unidecode opte pelo menor denominador comum.
Mark Ransom de
O Unidecode certamente vai para a solução independente de linguagem. Para uma solução centrada na Alemanha, converta caracteres aplicáveis ​​manualmente ( s/ö/oe/, etc.) antes de limpar o resto com unidecode.
alexis
4
De fato, em Finlandês por exemplo, enquanto ä -> a, ö -> oé completamente errado, ainda é preferível aeeoe
Antti Haapala
25

Na minha resposta original, também sugeri unicodedata.normalize. No entanto, decidi testá-lo e descobri que não funciona com aspas Unicode. Ele faz um bom trabalho na tradução de caracteres Unicode acentuados, então suponho que unicodedata.normalizeseja implementado usando a unicode.decompositionfunção, o que me leva a acreditar que provavelmente só pode lidar com caracteres Unicode que são combinações de uma letra e uma marca diacrítica, mas não estou um especialista na especificação Unicode, então eu poderia estar cheio de ar quente ...

Em qualquer caso, você pode usar unicode.translatepara lidar com caracteres de pontuação. O translatemétodo usa um dicionário de ordinais Unicode para ordinais Unicode, portanto, você pode criar um mapeamento que converte a pontuação somente Unicode em pontuação compatível com ASCII:

'Maps left and right single and double quotation marks'
'into ASCII single and double quotation marks'
>>> punctuation = { 0x2018:0x27, 0x2019:0x27, 0x201C:0x22, 0x201D:0x22 }
>>> teststring = u'\u201Chello, world!\u201D'
>>> teststring.translate(punctuation).encode('ascii', 'ignore')
'"hello, world!"'

Você pode adicionar mais mapeamentos de pontuação, se necessário, mas não acho que você necessariamente precise se preocupar em lidar com cada caractere de pontuação Unicode. Se você não precisa acentos punho e outros sinais diacríticos, você ainda pode usar unicodedata.normalizepara lidar com esses caracteres.

Mike Spross
fonte
21

Pergunta interessante.

O Google me ajudou a encontrar esta página que descreve usando o módulo unicodedata da seguinte forma:

import unicodedata
unicodedata.normalize('NFKD', title).encode('ascii','ignore')
cavalete
fonte