Normalisation du texte Unicode en une représentation standard en Python

Si vous voulez traiter des chaînes de caractères Unicode, mais vous avez besoin de vous assurer que toutes les chaînes de caractères ont la même représentation sous-jacente.

En Unicode, certains caractères peuvent être représentés par plus d’une séquence valide de points de code. Pour illustrer cela, prenons l’exemple suivant:

>>> s1 = 'Stephan Pizzi\u00f1o'

>>> s2 = 'Stephan Pizzin\u0303o'

>>> s1
'Stephan Pizziño'

>>> s2
'Stephan Pizziño'

>>> s1==s2
False

>>> len(s1)
15

>>> len(s2)
16

>>>

 

Ici, le texte “Stephan Pizzino” a été présenté sous deux formes. La première utilise le caractère “n” entièrement composé (U+00F1). La seconde utilise la lettre latine “n” suivie du caractère “~” (U+0303).

Avoir des représentations multiples est un problème pour les programmes qui comparent des chaînes de caractères. Pour résoudre ce problème, vous devez d’abord normaliser le texte en une représentation standard à l’aide du module unicodedata:

>>> import unicodedata

>>> s1 = 'Stephan Pizzi\u00f1o'
>>> s2 = 'Stephan Pizzin\u0303o'

>>> t1 = unicodedata.normalize('NFC', s1)
>>> t2 = unicodedata.normalize('NFC', s2)

>>> t1 == t2
True

>>> print(ascii(t1))
'Stephan Pizzi\xf1o'

>>> t3 = unicodedata.normalize('NFD', s1)
>>> t4 = unicodedata.normalize('NFD', s2)

>>> t3 == t4
True

>>> print(ascii(t3))
'Stephan Pizzin\u0303o'
>>>

 

Le premier argument de la fonction normalize() indique comment vous voulez que la chaîne soit normalisée. NFC signifie que les caractères doivent être entièrement composés (c.-à-d. utiliser un seul point de code si possible). NFD signifie que les caractères doivent être entièrement décomposés à l’aide de caractères combinés.

Python supporte également les formes de normalisation NFKC et NFKD, qui ajoutent des fonctionnalités de compatibilité supplémentaires pour traiter certains types de caractères. Par exemple:

>>> s = '\ufb01' # Un seul caractère
>>> s
'fi'
>>> unicodedata.normalize('NFD', s)
'fi'
# Observez comment les lettres combinées sont séparées ici
>>> unicodedata.normalize('NFKD', s)
'fi'
>>> unicodedata.normalize('NFKC', s)
'fi'
>>>

 

La normalisation est une partie importante de tout code qui a besoin de s’assurer qu’il traite le texte Unicode d’une manière saine et cohérente. Ceci est particulièrement vrai lorsque vous traitez des chaînes de caractères reçues dans le cadre d’une saisie utilisateur où vous avez peu de contrôle sur l’encodage.

La normalisation peut aussi être une partie importante de la vérification et du filtrage du texte. Supposons, par exemple, que vous souhaitiez supprimer toutes les signes distinctif d’un texte (éventuellement à des fins de recherche ou d’appariement):

>>> s1 = 'Stephan Pizzi\u00f1o'

>>> import unicodedata

>>> t1 = unicodedata.normalize('NFD', s1)

>>> ''.join(c for c in t1 if not unicodedata.combining(c))
'Stephan Pizzino'

>>>

 

Ce dernier exemple montre un autre aspect important du module unicodedata, à savoir les fonctions utilitaires pour tester les caractères par rapport aux classes de caractères.

La fonction combining() teste un caractère pour voir s’il s’agit d’un caractère de combinaison. Il y a d’autres fonctions dans le module pour trouver des catégories de caractères, tester des chiffres, etc.

LAISSER UN COMMENTAIRE

Please enter your comment!
Please enter your name here