Cours de Python / Extraire et vérifier du texte avec les expressions régulières
Une expression régulière repère un motif dans du texte ou vérifie la forme d’une chaîne entière. Une correspondance ne prouve pas que la date ou le montant extrait est valide : distinguez recherche, conversion et règles de l’application.
Choisir l’opération selon le besoin
| Opération | But |
|---|---|
| re.search | Trouver une première correspondance quelque part dans le texte. |
| re.fullmatch | Exiger que toute la chaîne corresponde au motif. |
| re.finditer | Parcourir les correspondances successives avec leurs groupes et positions. |
La recherche convient à l’extraction de plusieurs références dans un texte libre. Un formulaire attendant une seule référence complète demande un autre contrat : accepter une petite partie de sa saisie ne signifie pas accepter l’ensemble. La documentation du module re décrit ces opérations.
Les chaînes brutes, préfixées par r, simplifient l’écriture des antislashs en évitant une partie de leur interprétation par Python. Elles ne désactivent pas la syntaxe des chaînes Python : une chaîne brute ne peut notamment pas se terminer par un nombre impair d’antislashs. Le moteur de motifs interprète ensuite sa propre syntaxe.
Extraire des champs nommés et interpréter une date
Enregistrez le programme complet en UTF-8 dans regex_demo.py, dans un dossier d’exercice. re et datetime font partie de la bibliothèque standard ; aucun paquet externe n’est requis. Depuis ce dossier, lancez python regex_demo.py avec l’environnement virtuel du projet sélectionné. Utilisez python3 regex_demo.py si python3 est votre commande hors environnement virtuel sous macOS ou Ubuntu.
import re
from datetime import date
text = "A001:3500 B002:8000"
pattern = re.compile(r"(?P<id>[A-Z][0-9]{3}):(?P<amount>[0-9]+)")
for match in pattern.finditer(text):
print(match["id"], int(match["amount"]))
value = "2026-10-17"
if re.fullmatch(r"[0-9]{4}-[0-9]{2}-[0-9]{2}", value):
print(date.fromisoformat(value))
Résultat attendu :
A001 3500
B002 8000
2026-10-17
Le motif compilé attend une lettre de A à Z, exactement trois chiffres ASCII, deux-points, puis au moins un chiffre ASCII. {3} impose trois répétitions et + une ou plusieurs. Les groupes nommés id et amount rendent leur rôle lisible ; match["amount"] est encore une chaîne, que int convertit en nombre avant l’affichage.
Le motif de date vérifie uniquement quatre chiffres, deux chiffres et deux chiffres séparés par des tirets. La conversion date.fromisoformat vérifie ensuite le calendrier. Les règles de date, heure et fuseau horaire restent donc distinctes des règles du motif.
Traiter l’absence de résultat et les correspondances partielles
Lorsque search ou fullmatch échoue, le résultat est None. Après match = re.search(r"[0-9]+", "no digits"), vérifiez if match is not None: avant d’accéder à un groupe. Une boucle finditer sans correspondance n’exécute simplement pas son corps ; l’absence de ligne extraite n’est pas automatiquement signalée comme une erreur.
L’exemple ne définit pas de frontière autour des paires. Dans A001:3500.50, finditer peut extraire A001 et 3500, en ignorant la partie .50. Dans XA001:3500, il peut retrouver A001 au milieu du texte. Si ces entrées doivent être refusées comme paires entières, utilisez le motif compilé avec pattern.fullmatch(saisie), puis traitez explicitement None. N’interprétez pas une extraction partielle comme une validation des montants décimaux ou des identifiants plus longs.
De même, 2026-02-30 et 2026-99-99 correspondent à la forme de date mais ne sont pas des dates valides. Si ces valeurs viennent d’un utilisateur, placez la conversion dans un try/except ValueError et retournez une indication utile au lieu de laisser le programme s’arrêter. La référence de date.fromisoformat précise l’interprétation des dates.
La reconnaissance de quelques motifs ne remplace pas l’analyse d’un document complet. Pour un CSV avec champs entre guillemets, utilisez le module csv et ses lecteurs de champs. Pour HTML ou XML, choisissez un analyseur de la structure : le guide officiel des expressions régulières explique les limites des motifs improvisés pour ces formats.
Modifier une entrée à la fois et contrôler les limites
- Dans text, remplacez A001 par a001. La première paire n’est plus extraite ; la ligne B002 et la date sont encore affichées. Rétablissez A001.
- Remplacez seulement 3500 par -1. Le motif ne reconnaît pas le signe après les deux-points, donc la première paire disparaît de l’extraction. Il n’affiche pas pour autant un message de validation. Rétablissez 3500.
- Remplacez la date par 2026-02-30. La forme passe, puis le parseur lève ValueError après les deux lignes de paires. Rétablissez 2026-10-17.
- Essayez une saisie contenant une paire suivie d’un suffixe et comparez search à fullmatch. Le premier peut trouver une partie ; le second doit refuser l’ensemble si le suffixe n’appartient pas au motif.
Les bornes du motif sont des décisions : [0-9] exige ici des chiffres ASCII, tandis que d’autres catégories Unicode peuvent accepter davantage de chiffres. Le motif de montant accepte aussi zéro et des zéros initiaux ; int supprime leur présentation lors de la conversion. Si leur présence est interdite dans votre domaine, ajoutez une règle explicite.
Gardez les motifs sous contrôle et limitez la taille des entrées au besoin réel. Des répétitions imbriquées mal conçues peuvent demander beaucoup de travail sur une longue entrée qui échoue ; raccourcir l’entrée réduit l’exposition mais ne rend pas n’importe quel motif sûr. N’exécutez pas librement des motifs fournis par des utilisateurs comme s’il s’agissait de texte ordinaire, et préférez un traitement simple lorsque la complexité n’apporte rien.




