Les bases des expressions régulières
Une expression régulière (regex) est un motif qui décrit du texte. Ce guide présente les éléments de base que vous utiliserez le plus souvent et les pièges qui rendent les correspondances lentes ou inattendues.
Caractères littéraux et classes de caractères
La plupart des caractères correspondent à eux-mêmes : le motif cat trouve le texte « cat ». Certains caractères ont une signification spéciale, comme . * + ? ( ) [ ] { } ^ $ | \. Pour rechercher l’un d’eux littéralement, échappez-le avec une barre oblique inverse, par exemple \. pour un point.
Une classe de caractères correspond à un caractère parmi un ensemble. [abc] correspond à a, b ou c ; [a-z] à une lettre ASCII minuscule ; [^0-9] à tout ce qui n’est pas un chiffre. Les raccourcis courants sont \d (chiffre), \w (lettre, chiffre ou trait de soulignement), \s (espace blanc) et leurs contraires \D, \W et \S. Le point . correspond à n’importe quel caractère sauf un saut de ligne.
En JavaScript, \w et \d ne couvrent que les caractères ASCII. Pour trouver des lettres de n’importe quelle langue, utilisez une propriété Unicode comme \p{L} avec le drapeau u.
Quantificateurs et ancres
Les quantificateurs indiquent combien de fois l’élément précédent peut se répéter :
| Syntaxe | Signification | Exemple |
|---|---|---|
* | 0 ou plus | ab* correspond à a, ab, abbb |
+ | 1 ou plus | \d+ correspond à 7 ou 2026 |
? | 0 ou 1 | colou?r correspond à color et colour |
{n,m} | Entre n et m | \d{2,4} correspond à 2 à 4 chiffres |
Les ancres correspondent à une position plutôt qu’à un caractère. ^ désigne le début et $ la fin de l’entrée (ou de chaque ligne avec le drapeau m). \b est une limite de mot : \bcat\b trouve « cat » mais pas « concatenate ». Pour valider une valeur entière, ancrez les deux extrémités : ^\d{5}$ accepte exactement cinq chiffres et rien d’autre.
Groupes et captures
Les parenthèses regroupent une partie d’un motif pour qu’un quantificateur ou une alternative s’y applique : (ab)+ répète « ab », et (jpg|png) correspond à l’un ou l’autre mot. Un groupe normal capture aussi le texte trouvé, que vous pouvez réutiliser dans un remplacement sous la forme $1, $2, etc.
Les groupes nommés comme (?<year>\d{4}) rendent les motifs plus lisibles et peuvent être référencés par $<year>. Si vous avez seulement besoin de regrouper, un groupe non capturant (?:...) évite de créer une capture inutile. Le testeur RegEx de LeedyBox liste chaque correspondance avec ses groupes de capture et prévisualise les remplacements.
Drapeaux
Les drapeaux modifient le comportement de l’ensemble du motif. Les drapeaux JavaScript courants sont :
g(global) : trouver toutes les correspondances au lieu de la première seulement.i(ignore case) : ne pas distinguer majuscules et minuscules.m(multiline) :^et$correspondent à chaque saut de ligne.s(dotAll) :.correspond aussi aux sauts de ligne.u(unicode) : active la correspondance compatible Unicode et les classes\p{...}.
JavaScript dispose aussi de y (sticky) et d (indices des correspondances), que le testeur prend également en charge.
Gourmand ou paresseux, et retour arrière catastrophique
Par défaut, les quantificateurs sont gourmands : ils prennent autant de caractères que possible, puis en rendent si la suite du motif échoue. Sur le texte <b>bold</b>, le motif <.+> correspond à toute la chaîne. Ajouter ? rend le quantificateur paresseux : <.+?> correspond alors à <b> seul. Une classe négative comme <[^>]+> est souvent plus claire et plus rapide.
La plupart des moteurs d’expressions régulières, dont celui de JavaScript, fonctionnent par retour arrière. Des quantificateurs imbriqués comme (a+)+$ ou des alternatives qui se chevauchent peuvent amener le moteur à essayer un nombre énorme de combinaisons lorsqu’une correspondance échoue, ce qui peut figer une page ou un serveur. C’est ce qu’on appelle le retour arrière catastrophique ; avec des entrées non fiables, il peut servir à des attaques par déni de service (ReDoS). Évitez d’imbriquer des quantificateurs portant sur les mêmes caractères, préférez des classes précises à .* et testez les motifs avec de longues entrées qui ne correspondent pas.
Les variantes de regex diffèrent
Il n’existe pas de norme unique pour les expressions régulières. JavaScript, Python, Java, .NET, PCRE (utilisé par PHP), Go et les bases de données prennent chacun en charge une syntaxe légèrement différente. Les assertions arrière, les quantificateurs possessifs, la syntaxe des groupes nommés, les classes Unicode et la syntaxe de remplacement varient. Le moteur RE2 de Go, par exemple, ne prend en charge ni les assertions avant/arrière ni les références arrière.
Le testeur RegEx de LeedyBox utilise le moteur JavaScript de votre navigateur. Un motif qui fonctionne ici peut nécessiter des modifications dans un autre langage : testez-le de nouveau là où il sera exécuté.
Questions fréquentes
Pourquoi mon motif ne trouve-t-il que la première occurrence ?
Sans le drapeau g, JavaScript s’arrête après la première correspondance. Activez g pour trouver toutes les correspondances.
Une regex peut-elle valider des adresses e-mail ?
Une regex peut vérifier qu’une valeur semble plausible, mais elle ne peut pas confirmer qu’une adresse existe. L’envoi d’un e-mail de confirmation est la méthode habituelle pour la vérifier.
Pourquoi ^ ne correspond-il qu’une fois dans un texte de plusieurs lignes ?
Par défaut, ^ et $ portent sur l’entrée entière. Activez le drapeau m pour qu’ils correspondent au début et à la fin de chaque ligne.