Guide complet des expressions régulières (Regex)
Les regex semblent cryptiques au premier regard. Comprendre leur logique interne les rend prévisibles — et c'est un outil que vous utiliserez toute votre carrière.
Une expression régulière est un mini-langage pour décrire des patterns dans du texte. \b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b semble illisible — mais chaque symbole a une signification précise, et une fois que vous connaissez le vocabulaire, vous pouvez le lire comme une phrase.
Les regex sont présentes partout : validation de formulaires, parsing de logs, recherche dans des éditeurs, commandes grep, scripts de déploiement. Investir deux heures pour comprendre leur logique vous économisera des centaines d'heures de code ad hoc.
Les caractères littéraux et le premier pattern
La regex la plus simple : un caractère correspond à lui-même.
helloCette regex correspond à la chaîne "hello" n'importe où dans le texte. Sensible à la casse par défaut.
const text = 'Dites hello au monde'
/hello/.test(text) // true
/Hello/.test(text) // false
/Hello/i.test(text) // true — flag i = insensible à la casseMétacaractères : les symboles spéciaux
| Symbole | Signification |
|---|---|
. | N'importe quel caractère sauf newline |
\d | Chiffre (0-9) |
\D | Non-chiffre |
\w | Mot (lettres, chiffres, _) |
\W | Non-mot |
\s | Espace blanc (space, tab, newline) |
\S | Non-espace |
\n | Newline |
\t | Tabulation |
\\ | Backslash littéral |
\. | Point littéral (échapper le .) |
\d\d\d-\d\d-\d\d\d\d ← format SSN américain (123-45-6789)
\w+@\w+\.\w+ ← email simplifié
\d{4}-\d{2}-\d{2} ← date ISO (2026-06-18)Classes de caractères []
Les crochets définissent un ensemble de caractères possibles à une position.
[aeiou] → une voyelle
[a-z] → une minuscule
[A-Z] → une majuscule
[0-9] → un chiffre (équivalent à \d)
[a-zA-Z0-9] → alphanumérique
[^aeiou] → non-voyelle (^ dans [] = négation)
[.,;!?] → ponctuation (caractères littéraux dans [])const phone = '06-12-34-56-78'
/^0[67][-. ]?(\d{2}[-. ]?){4}$/.test(phone) // true — numéro mobile FRQuantificateurs
Les quantificateurs s'appliquent à l'élément qui les précède.
| Quantificateur | Signification |
|---|---|
* | 0 ou plus |
+ | 1 ou plus |
? | 0 ou 1 (optionnel) |
{n} | Exactement n fois |
{n,} | n fois ou plus |
{n,m} | Entre n et m fois |
colou?r → color ou colour (u optionnel)
\d+ → un ou plusieurs chiffres
\d{4} → exactement 4 chiffres
\d{2,4} → 2 à 4 chiffres
.* → n'importe quoi (greedy — prend le maximum)
.+? → n'importe quoi (lazy — prend le minimum)Greedy vs Lazy
const html = '<b>gras</b> et <i>italique</i>'
html.match(/<.+>/)[0] // '<b>gras</b> et <i>italique</i>' — greedy, prend tout
html.match(/<.+?>/)[0] // '<b>' — lazy, s'arrête dès que possibleAjoutez ? après un quantificateur pour le rendre lazy : *?, +?, {n,m}?.
Ancres
Les ancres ne correspondent pas à des caractères — elles correspondent à des positions.
| Ancre | Position |
|---|---|
^ | Début de chaîne (ou début de ligne avec flag m) |
$ | Fin de chaîne |
\b | Frontière de mot |
\B | Non-frontière de mot |
^Hello → chaîne qui commence par "Hello"
world$ → chaîne qui finit par "world"
^Hello world$ → chaîne exactement égale à "Hello world"
\bcat\b → "cat" comme mot entier (pas "category", pas "concatenate")Groupes
Les parenthèses groupent des parties de la regex.
// Groupe de capture — capture la valeur
const date = '2026-06-18'
const match = date.match(/(\d{4})-(\d{2})-(\d{2})/)
match[1] // '2026' — année
match[2] // '06' — mois
match[3] // '18' — jour
// Groupe nommé — plus lisible
const match = date.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/)
match.groups.year // '2026'
match.groups.month // '06'
// Groupe non-capturant — groupe sans capture (juste pour la logique)
/(?:https?|ftp):\/\//.test('https://exemple.com') // true
// Alternation dans un groupe
/(?:jpg|jpeg|png|gif|webp)$/i.test('photo.jpg') // trueLookahead et lookbehind
Les "lookaround" permettent de vérifier ce qui precède ou suit sans l'inclure dans le match.
# Lookahead positif (?=...) — ce qui suit doit correspondre
\d+(?= euros) → chiffres suivis de " euros" (capture les chiffres, pas " euros")
# Lookahead négatif (?!...) — ce qui suit ne doit PAS correspondre
\d+(?! euros) → chiffres non suivis de " euros"
# Lookbehind positif (?<=...) — ce qui précède doit correspondre
(?<=€)\d+ → chiffres précédés de "€"
# Lookbehind négatif (?<!...) — ce qui précède ne doit PAS correspondre
(?<!€)\d+ → chiffres non précédés de "€"const prices = ['100 euros', '200 dollars', '€50', '30 euros']
// Extraire les montants en euros uniquement
prices.join('\n').match(/\d+(?= euros)/g) // ['100', '30']
prices.join('\n').match(/(?<=€)\d+/g) // ['50']Flags
Les flags modifient le comportement global de la regex.
| Flag | Effet |
|---|---|
g | Global — trouver toutes les occurrences |
i | Case insensitive |
m | Multiline — ^ et $ s'appliquent à chaque ligne |
s | Dotall — . correspond aussi aux newlines |
u | Unicode — support des caractères Unicode |
d | Indices — retourne les positions des captures |
'hello HELLO HeLLo'.match(/hello/gi) // ['hello', 'HELLO', 'HeLLo']
const text = 'ligne1\nligne2\nligne3'
text.match(/^\w+/gm) // ['ligne1', 'ligne2', 'ligne3']
// Sans m : ['ligne1'] — ^ = début de la chaîne entière
// Remplacer avec g
'aabbcc'.replace(/[abc]/g, 'x') // 'xxxxxx'
'aabbcc'.replace(/[abc]/, 'x') // 'xabbcc' — sans g, premier match seulementMéthodes JavaScript
const regex = /\d+/g
const text = 'J ai 28 ans et 3 chats'
// test — retourne boolean
regex.test(text) // true
// match — retourne les matches
text.match(/\d+/g) // ['28', '3']
text.match(/(\d+)/) // ['28', '28', index: 6, ...] — avec captures
// matchAll — itérateur avec captures pour chaque match
for (const match of text.matchAll(/(\d+)/g)) {
console.log(match[0], match.index) // '28' 6, puis '3' 17
}
// search — retourne l'index du premier match
text.search(/\d+/) // 6
// replace — remplacer
text.replace(/\d+/g, '#') // 'J ai # ans et # chats'
text.replace(/(\d+)/g, '[$1]') // 'J ai [28] ans et [3] chats'
text.replace(/(\d+)/g, (m) => m * 2) // 'J ai 56 ans et 6 chats'
// replaceAll — remplacer toutes les occurrences (ES2021)
text.replaceAll('a', '@') // remplace tous les 'a' (plus simple qu'une regex pour les littéraux)
// split — couper avec une regex
'un,deux;trois'.split(/[,;]/) // ['un', 'deux', 'trois']Cas pratiques
// Email (version robuste)
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
emailRegex.test('william@iducation.fr') // true
emailRegex.test('pas-un-email') // false
// URL
const urlRegex = /^https?:\/\/[^\s/$.?#].[^\s]*$/i
urlRegex.test('https://iducation.fr/articles') // true
// Mot de passe fort (8+ chars, 1 majuscule, 1 chiffre, 1 spécial)
const pwdRegex = /^(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/
pwdRegex.test('MonMdp1!') // true
pwdRegex.test('faible') // false
// Numéro de téléphone français
const telFR = /^(?:\+33|0033|0)[1-9](?:[\s.-]?\d{2}){4}$/
telFR.test('06 12 34 56 78') // true
telFR.test('+33612345678') // true
// Slug URL
const slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/
slugRegex.test('mon-article-2026') // true
slugRegex.test('Mon Article') // false
// Extraire des valeurs d'une log line
const log = '[2026-06-18 14:32:01] ERROR: Connection timeout (attempt 3/5)'
const { groups } = log.match(/\[(?<date>[^\]]+)\] (?<level>\w+): (?<msg>.+)/)
// groups.date → '2026-06-18 14:32:01'
// groups.level → 'ERROR'
// groups.msg → 'Connection timeout (attempt 3/5)'Regex avec grep et les commandes Linux
Les regex s'utilisent directement dans le terminal — l'une des applications les plus fréquentes. Parmi les commandes Linux essentielles, grep est celle qui bénéficie le plus des regex.
# Chercher les erreurs dans les logs
grep -E 'ERROR|WARN' app.log
grep -E '\[2026-06-18\]' access.log
# Trouver des IPs dans un fichier
grep -oE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' fichier.txt
# Extraire les URLs
grep -oE 'https?://[^\s]+' page.html
# Fichiers contenant une regex
grep -rE 'password\s*=' src/ # DANGER — chercher des mots de passe hardcodésLa validation des entrées côté serveur s'appuie souvent sur des regex pour les formats stricts (email, slug, codes). Côté client, les regex permettent de donner un feedback immédiat sans aller en base.
Tester vos regex
Avant d'intégrer une regex en production, testez-la sur des données réelles :
- regex101.com — explication de chaque partie, tests en temps réel, plusieurs langages
- regexr.com — interface visuelle avec bibliothèque de patterns
- En JavaScript :
new RegExp(pattern, flags)dans la console
La maîtrise des regex s'acquiert progressivement. Commencez par les cas simples — valider un email, extraire des chiffres, chercher un mot — et construisez sur cette base. Cinq minutes à comprendre une regex vaut mieux que trente lignes de code qui fait la même chose.