Comment filtrer et nettoyer un texte en Python

Supposant q’un utilisateur a saisi le texte “pýtĥöñ” dans un formulaire sur un de vos programmes Python et vous aimeriez le nettoyer d’une manière ou d’une autre.

Le problème de filtrage et du nettoyage du texte s’applique à une grande variété de problèmes impliquant l’analyse du texte et le traitement des données.

À un niveau très simple, vous pouvez utiliser les fonctions de base des chaînes de caractères (par exemple, str.upper() et str.lower()) pour convertir le texte en un format standard.

Les remplacements simples utilisant les méthodes replace() ou sub() de la classe str peuvent se concentrer sur la suppression ou la modification de séquences de caractères très spécifiques. Vous pouvez également normaliser le texte à l’aide de Unicode data.normalize().

Cependant, vous voudrez peut-être aller plus loin dans le processus de filtrage. Peut-être, par exemple, voulez-vous éliminer des plages entières de caractères ou effacer des signes accentués de diacritiques.

Pour ce faire, vous pouvez vous tourner vers la méthode str.translate(). Pour illustrer son utilisation, supposons que vous ayez une chaîne de caractères telle que la suivante:

>>> s = 'pýtĥöñ\fis\tawesome\r\n'

>>> s
'pýtĥöñ\x0cis\tawesome\r\n'

>>>

 

La première étape consiste à nettoyer les espaces blancs. Pour ce faire, créez une petite table de traduction et utilisez la méthode translate():

>>> s = 'pýtĥöñ\fis\tawesome\r\n'
>>> table_traduction = {
... ord('\t') : ' ',
... ord('\f') : ' ',
... ord('\r') : None # Supprimé
... }
>>> a = s.translate(table_traduction)
>>> a
'pýtĥöñ is awesome\n'
>>>

 

Comme vous pouvez le voir ici, les caractères blancs tels que \t et \f ont été transformés en un seul espace. Le retour chariot \r a été entièrement supprimé.

Vous pouvez aller plus loin dans cette idée de mappage et construire des tables beaucoup plus grandes. Par exemple, supprimons tous les caractères de combinaison:

>>> import unicodedata
>>> import sys
>>> caracteres_combinaison = dict.fromkeys(c for c in range(sys.maxunicode)
... if unicodedata.combining(chr(c)))
...
>>> b = unicodedata.normalize('NFD', a)
>>> b
'pýtĥöñ est incroyable\n'
>>> b.translate(caracteres_combinaison)
'python est incroyable\n'
>>>

 

Dans ce dernier exemple, un dictionnaire mappant chaque caractère Unicode combinant à la valeur None est créé à l’aide de la méthode dict.fromkeys().

L’entrée originale est ensuite normalisée sous une forme décomposée en utilisant unicodedata.normalize(). De là, la fonction translate() est utilisée pour supprimer tous les accents. Des techniques similaires peuvent être utilisées pour supprimer d’autres types de caractères (par exemple, caractères de contrôle, etc.).

Comme autre exemple, voici une table de traduction qui mappe tous les chiffres décimaux Unicode à leur équivalent en ASCII:

>>> map_chiffres = { c: ord('0') + unicodedata.digit(chr(c))
... 	for c in range(sys.maxunicode)
... 	if unicodedata.category(chr(c)) == 'Nd' }
...

>>> len(map_chiffres)
460

>>> # chiffres arabes
>>> x = '\u0661\u0662\u0663'
>>> x.translate(map_chiffres)
'123'

>>>

 

Une autre technique de nettoyage du texte consiste à utiliser des fonctions de décodage et d’encodage des entrées/sorties. L’idée ici est d’abord de faire un nettoyage préliminaire du texte, puis de lui appliquer une combinaison d’opérations encode() ou de decode() pour le filtrer ou le modifier. Par exemple:

>>> a = 'pýtĥöñ est fantastique\n'

>>> b = unicodedata.normalize('NFD', a)
>>> b.encode('ascii', 'ignore').decode('ascii')
'python est fantastique\n'

>>>

 

Ici, le processus de normalisation a décomposé le texte original en caractères avec des caractères de combinaison séparés. L’encodage/décodage ASCII consécutif a simplement éliminé tous ces caractères d’un seul coup d’œil.

Naturellement, cela ne fonctionnerait que si l’objectif final était d’obtenir une représentation ASCII.

Un problème majeur avec le nettoyage de texte peut être la performance d’exécution. En règle générale, plus il est simple, plus il sera rapide. Pour les remplacements simples, la méthode str.replace() est souvent l’approche la plus rapide, même si vous devez l’appeler plusieurs fois.

Par exemple, pour nettoyer les espaces blancs, vous pouvez utiliser un code suivant:

def nettoyer_espaces(s):
   s = s.replace('\r', '')
   s = s.replace('\t', ' ')
   s = s.replace('\f', ' ')
   return s

 

Si vous l’essayez, vous constaterez qu’il est un peu plus rapide qu’en utilisant translate() ou une approche utilisant une expression régulière.

D’autre part, la méthode translate() est très rapide si vous avez besoin d’effectuer un mappage ou une suppression non trivial de caractère à caractère.

Dans l’ensemble, la performance est quelque chose que vous devrez étudier à fond dans votre application particulière. Malheureusement, il est impossible de suggérer une technique spécifique qui fonctionne le mieux dans tous les cas, alors essayez différentes approches et mesurez la performance de votre code.

Bien que l’accent de cet article ait été mis sur les chaînes de caractères, des techniques similaires peuvent être appliquées aux octets, y compris les remplacements simples, la traduction et les expressions régulières.

LAISSER UN COMMENTAIRE

Please enter your comment!
Please enter your name here