Quand utiliser regex
Les expressions régulières sont un petit langage pour décrire des motifs de texte. Elles sont puissantes et faciles à surutiliser.
Avant de tendre la main vers re, demande-toi si les méthodes de chaîne simples feraient l'affaire. .split(), .replace(), .startswith(), "target" in text — celles-ci sont plus rapides, plus lisibles et moins sujettes aux erreurs que le regex équivalent. Garde regex pour quand le motif qui t'intéresse est vraiment structuré mais trop flexible pour des opérations de chaîne fixes : adresses email, numéros de téléphone, lignes de log aux formes connues, extraits HTML ou Markdown, toute recherche « trouve ce genre de chose ».
Le vocabulaire de base
Un motif regex est une chaîne qui décrit ce que tu cherches. Quelques briques :
.— n'importe quel caractère unique\d— n'importe quel chiffre (0–9)\w— n'importe quel caractère « mot » (lettre, chiffre, underscore)\s— n'importe quel caractère d'espacement^— début de la chaîne$— fin de la chaîne[abc]— l'un parmi a, b ou c[^abc]— n'importe quel caractère sauf a, b, ca|b— a ou b*— zéro ou plus de la chose précédente+— un ou plus?— zéro ou un{3}— exactement 3{2,5}— entre 2 et 5( ... )— groupe (capture ce qui correspond à l'intérieur)
C'est assez pour la plupart des regex du monde réel.
Les fonctions clés
re.search(pattern, text) trouve la première correspondance n'importe où dans la chaîne. Renvoie un objet match ou None :
Utilise toujours une raw string (r"...") pour les motifs regex. Sinon Python essaie d'interpréter les barres obliques inverses comme des échappements de chaîne et tu obtiens un motif différent de celui que tu as tapé.
re.match(pattern, text) ressemble à search mais ne correspond qu'au début :
La plupart du temps, tu veux search.
re.findall(pattern, text) renvoie toutes les correspondances non chevauchantes comme liste :
Note que findall renvoie des chaînes, pas des objets match. Si tu as un motif avec un groupe, tu récupères le contenu du groupe. Avec plusieurs groupes, tu obtiens une liste de tuples.
Groupes de capture
Les parenthèses dans un motif capturent tout ce qui correspond à l'intérieur :
Les groupes nommés sont généralement plus clairs :
Une fois que le regex a plus d'un groupe, les nommer rend le code d'extraction beaucoup plus facile à suivre.
Remplacement avec re.sub
re.sub(pattern, replacement, text) remplace chaque correspondance :
Ça supprime tout ce qui n'est pas un chiffre. Le remplacement peut référencer les groupes capturés avec \1, \2, etc. — ou dans des raw strings, \g<1> est plus clair :
Tu peux aussi passer une fonction comme remplacement. C'est utile pour des transformations qui ne sont pas un simple échange :
Compiler des motifs pour les réutiliser
Si tu utilises le même motif plusieurs fois — surtout en boucle — compile-le une fois :
Les motifs compilés exposent les mêmes méthodes — search, match, findall, sub — sans le motif comme premier argument. Légèrement plus efficace, souvent plus lisible.
Flags
Modificateurs courants, passés comme argument flags= ou combinés avec OR :
re.IGNORECASE(re.I) — correspondance insensible à la casse.re.MULTILINE(re.M) —^et$correspondent à chaque ligne, pas juste aux bornes de la chaîne.re.DOTALL(re.S) —.correspond aussi aux retours à la ligne (par défaut non).re.VERBOSE(re.X) — permet espaces et commentaires#dans le motif, pour la lisibilité.
re.VERBOSE est particulièrement utile pour des motifs complexes :
Les regex multi-lignes et commentés sont bien plus faciles à maintenir que des one-liners opaques.
Gourmand vs paresseux
Les quantificateurs (*, +, ?, {n,}) sont gourmands par défaut — ils correspondent au maximum. Ajoute un ? pour les rendre paresseux :
La version gourmande capture toute la sous-chaîne de <b> à </i> — probablement pas ce que tu voulais. Le .+? paresseux s'arrête au premier >.
(Note : ne parse pas réellement du HTML avec regex en production. Utilise html.parser ou BeautifulSoup. L'exemple ci-dessus sert juste à illustrer la gourmandise.)
Un exemple réaliste
Parser des lignes d'un format de log simple :
Beaucoup de puissance dans pas beaucoup de lignes.
Quelques habitudes
- Utilise toujours des raw strings pour les motifs.
- Commence avec le motif le plus simple qui marche ; resserre ensuite.
- Utilise des groupes nommés dès que tu en as plus d'un.
- Compile les motifs que tu vas réutiliser.
- Regex est plus lent que les méthodes de chaîne simples. Si
.split()fait l'affaire, utilise.split().
Ensuite : erreurs et débogage
Ça clôt le tour des données du monde réel — fichiers, JSON, CSV, HTTP, dates et regex. Tout dans un vrai programme finit par heurter une erreur, cependant, et bien lire les tracebacks Python est la plus grande compétence de débogage que tu puisses acquérir. Le dernier chapitre couvre les exceptions et les erreurs spécifiques que tu rencontreras le plus souvent.
Questions fréquentes
Qu'est-ce que regex en Python ?
Une expression régulière (regex) est un petit langage pour décrire des motifs dans du texte. Le module re de Python te permet de chercher des motifs, d'extraire des morceaux et de remplacer des correspondances. C'est exagéré pour des opérations simples sur chaîne — utilise les méthodes comme .split() ou .replace() d'abord — mais imbattable pour la correspondance de motifs structurés.
Quelle est la différence entre re.match et re.search ?
re.match ne correspond qu'au début de la chaîne. re.search parcourt toute la chaîne et trouve la première correspondance n'importe où. Dans le doute, utilise search — il correspond mieux à l'intuition humaine.
Dois-je toujours utiliser des raw strings pour les motifs regex ?
Oui. Les motifs regex contiennent souvent des barres obliques inverses (\d, \s, \b), que les chaînes Python interprètent comme des séquences d'échappement. Préfixer avec r — r'\d+' — dit à Python de prendre la chaîne littéralement, ce qui garde le regex lui-même lisible.