2009-01-15 7 views

Répondre

7

Je pense que vous cherchez ceci:

>>> import unicodedata  
>>> print unicodedata.normalize("NFC",u"c\u0327") 
ç 
+1

Oui, cela fonctionne - en supposant que j'ai vraiment décomposé unicode. Malheureusement, il semble que j'ai (par exemple) \ u00B8 (cedilla) au lieu de \ u0327 (en combinant cedilla) dans mon texte. On dirait que je devrais soit mapper ces caractères à leur équivalent de combinaison ou tout simplement les dépouiller entièrement. Merci. – msanders

1

Je ne peux pas vraiment vous donner un définitif réponds à ta question parce que je n'ai jamais essayé ça. Mais il y a un unicodedata module dans la bibliothèque standard. Il a deux fonctions decomposition() et normalize() qui pourraient vous aider ici.

Éditer: Assurez-vous qu'il est vraiment décomposé unicode. Parfois, il y a des façons bizarres d'écrire des caractères qui ne peuvent pas être directement exprimés dans un encodage. Comme "a qui est destiné à être mentalement analysé par un humain ou un programme spécialisé comme ä.

+0

Vous avez raison, ce n'est pas vraiment unicode décomposé - voir mon commentaire sur la réponse de Rafał Dowgird. – msanders

5

Malheureusement, il semble que j'ai fait (par exemple) \ u00B8 (cédille) au lieu de \ u0327 (combinant cédille) dans mon texte.

Eurgh, méchant! Vous pouvez toujours le faire automatiquement, bien que le processus ne soit pas entièrement sans perte car il implique une décomposition de compatibilité (NFKD).

Normaliser U + 00B8 à NFKD et vous obtiendrez un espace suivi par le U + 0327. Vous pouvez ensuite parcourir la chaîne à la recherche de tout espace-suivi-par-combinaison-caractère, et supprimer l'espace. Recomposer finalement à NFC pour mettre les caractères de combinaison sur le caractère précédent à la place.

s= unicodedata.normalize('NFKD', s) 
s= ''.join(c for i, c in enumerate(s) if c!=' ' or unicodedata.combining(s[i+1])==0) 
s= unicodedata.normalize('NFC', s)