Où est le «meilleur ASCII de Python pour cette base de données Unicode»?

85

J'ai du texte qui utilise la ponctuation Unicode, comme les guillemets doubles à gauche, les guillemets simples à droite pour l'apostrophe, etc., et j'en ai besoin en ASCII. Python a-t-il une base de données de ces caractères avec des substituts ASCII évidents pour que je puisse faire mieux que de les transformer tous en "?" ?

Joeforker
la source
21
Vous êtes un guerrier courageux. Unicode est l'ennemi juré de Python.
David Berger
2
Les personnes qui trouvent cela pourraient être intéressées par Quelle est la meilleure façon de supprimer les accents dans une chaîne Unicode Python?
Martin Thoma

Réponses:

89

Unidecode ressemble à une solution complète. Il convertit les citations fantaisie en guillemets ascii, les caractères latins accentués en caractères non accentués et tente même la translittération pour traiter les caractères qui n'ont pas d'équivalents ASCII. De cette façon, vos utilisateurs n'ont pas besoin de voir un tas de? lorsque vous deviez faire passer leur texte via un ancien système ascii 7 bits.

>>> 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
la source
3
Hm .. les trémas allemands sont convertis en leur caractère de base au lieu de par exemple ö = oe, ä = ae, etc.
ThiefMaster
4
@ThiefMaster est-ce que ces équivalents sont vrais dans toutes les langues? Peut-être que Unidecode est le plus petit dénominateur commun.
Mark Ransom
Unidecode est certainement la solution indépendante de la langue. Pour une solution centrée sur l'allemand, convertissez manuellement les caractères applicables ( s/ö/oe/, etc.) avant de nettoyer le reste avec unidecode.
alexis le
4
En effet, en finnois par exemple, alors que ä -> a, ö -> oest carrément faux, il est toujours préférable de aeetoe
Antti Haapala
25

Dans ma réponse originale, j'ai également suggéré unicodedata.normalize. Cependant, j'ai décidé de le tester et il s'avère que cela ne fonctionne pas avec les guillemets Unicode. Il fait un bon travail en traduisant les caractères Unicode accentués, donc je suppose qu'il unicodedata.normalizeest implémenté à l'aide de la unicode.decompositionfonction, ce qui me porte à croire qu'il ne peut probablement gérer que les caractères Unicode qui sont des combinaisons d'une lettre et d'un signe diacritique, mais je ne suis pas vraiment un expert sur la spécification Unicode, donc je pourrais juste être plein d'air chaud ...

Dans tous les cas, vous pouvez utiliser unicode.translatepour traiter les caractères de ponctuation à la place. La translateméthode prend un dictionnaire d'ordinaux Unicode en ordinaux Unicode, vous pouvez donc créer un mappage qui traduit la ponctuation Unicode uniquement en ponctuation compatible 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!"'

Vous pouvez ajouter plus de mappages de ponctuation si nécessaire, mais je ne pense pas que vous ayez nécessairement à vous soucier de la gestion de chaque caractère de ponctuation Unicode. Si vous ne devez accents de poignée et d' autres marques diacritiques, vous pouvez toujours utiliser unicodedata.normalizepour faire face à ces personnages.

Mike Spross
la source
21

Question interessante.

Google m'a aidé à trouver cette page qui décrit l'utilisation du module unicodedata comme suit:

import unicodedata
unicodedata.normalize('NFKD', title).encode('ascii','ignore')
chevalet
la source
3

Il y a une discussion supplémentaire à ce sujet à http://code.activestate.com/recipes/251871/ qui a la solution NFKD et quelques façons de faire une table de conversion, pour des choses comme ± => +/- et d'autres caractères non alphabétiques.

Andrew Dalke
la source