Aide-Mémoire Regex : Guide Complet des Expressions Régulières

Maîtrisez les expressions régulières avec ce guide complet. Apprenez les patterns, la syntaxe, les implémentations spécifiques aux langages (Python, JavaScript, PHP, C#, Java, Go, Ruby), les transformations rechercher/remplacer dans VS Code et plus de 200 exemples pratiques. La ressource ultime sur les regex pour débutants et experts.

G
GUi Softworks
60 min de lecture

Qu'est-ce qu'une Regex ?

Les expressions régulières (regex ou regexp) sont des séquences de caractères qui définissent des patterns de recherche. Elles constituent l'un des outils les plus puissants pour le traitement de texte, la reconnaissance de patterns et l'extraction de données.

Pourquoi Utiliser les Expressions Régulières ?

Les regex sont essentielles pour :

  • Validation de formulaires (emails, numéros de téléphone, mots de passe)
  • Extraction de données (analyse de logs, scraping de pages web)
  • Traitement de texte (rechercher et remplacer, formatage)
  • Refactoring de code (renommer des variables, mettre à jour la syntaxe)
  • Nettoyage d'entrées (sécurité, prévention des attaques par injection)

Comment Lire Cet Aide-Mémoire

Ce guide est organisé en sections progressives :

  1. Fondamentaux - Syntaxe et patterns de base
  2. Fonctionnalités Avancées - Lookaround, groupes nommés, Unicode
  3. Spécifique au Langage - Exemples en Python, JavaScript, PHP, C#, Java, Go, Ruby
  4. Regex dans VS Code - Transformations rechercher/remplacer avec plus de 20 exemples
  5. Patterns Courants - Patterns prêts à copier-coller pour emails, URLs, dates, etc.
  6. Cas d'Usage Pratiques - Applications du monde réel
  7. Résolution de Problèmes - Erreurs courantes et conseils de performance

Chaque section comprend :

  • Des explications claires
  • Des exemples visuels
  • Des extraits de code que vous pouvez copier
  • Des astuces professionnelles et pièges à éviter

Caractères Littéraux

La regex la plus simple est une séquence de caractères littéraux :

abc

Correspond à : "abc" dans "La séquence abc"

Sensibilité à la Casse

Par défaut, les regex sont sensibles à la casse :

  • Bonjour correspond à "Bonjour" mais PAS à "bonjour"
  • Utilisez le flag i pour une correspondance insensible à la casse : /bonjour/i

Caractères Spéciaux (Métacaractères)

Ces 12 caractères ont une signification spéciale dans les regex et doivent être échappés avec \ pour correspondre littéralement :

. ^ $ * + ? { } [ ] \ | ( )

Exemples :

  • \. correspond à un point littéral
  • \€ correspond à un symbole euro
  • \( correspond à une parenthèse littérale
Caractère Échappement Exemple Correspond
. (point) \. 3\.14 "3.14"
(euro) \€ \€100 "€100"
* (astérisque) \* a\*b "a*b"

Classes de Caractères

Classes de Caractères Prédéfinies

Pattern Description Équivalent Exemple Correspond
\d N'importe quel chiffre [0-9] \d\d "42"
\D N'importe quel non-chiffre [^0-9] \D+ "abc"
\w Caractère mot [a-zA-Z0-9_] \w+ "bonjour_123"
\W Caractère non-mot [^a-zA-Z0-9_] \W "@", "#"
\s Espace blanc [ \t\n\r\f\v] \s+ " " (espaces)
\S Non-espace [^ \t\n\r\f\v] \S+ "bonjour"
. N'importe quel caractère sauf newline - a.c "abc", "a1c"

Astuce Pro : \w N'inclut PAS les lettres Unicode par défaut. Utilisez \p{L} pour le support Unicode (JavaScript/Python).

Classes de Caractères Personnalisées

Pattern Description Exemple Correspond
[abc] Correspond à n'importe lequel de a, b, ou c [aeiou] Voyelles : "a", "e", "i", "o", "u"
[^abc] Correspond à tout sauf a, b, ou c [^0-9] Non-chiffres
[a-z] Plage : lettres minuscules [a-z]+ "bonjour"
[A-Z] Plage : lettres majuscules [A-Z]+ "BONJOUR"
[0-9] Plage : chiffres [0-9]{4} "2025"
[a-zA-Z] Combiné : toutes les lettres [a-zA-Z0-9] Alphanumérique

Exemples :

[aeiou]       → Correspond à n'importe quelle voyelle
[^aeiou]      → Correspond à n'importe quelle consonne (non-voyelle)
[a-z0-9]      → Correspond aux lettres minuscules et chiffres
[a-zA-Z0-9_]  → Identique à \w (caractères mot)

Quantificateurs

Les quantificateurs spécifient combien de fois un pattern doit correspondre.

Quantificateurs de Base

Pattern Description Exemple Correspond
* 0 ou plus ab*c "ac", "abc", "abbc", "abbbc"
+ 1 ou plus ab+c "abc", "abbc" (PAS "ac")
? 0 ou 1 (optionnel) colou?r "color", "colour"
{n} Exactement n fois \d{4} "2025" (exactement 4 chiffres)
{n,} n ou plus fois \d{2,} "42", "123", "9999"
{n,m} Entre n et m fois \d{2,4} "42", "123", "2025"

Quantificateurs Gourmands vs. Paresseux

Gourmand (par défaut) : Correspond au maximum possible

<.*>      → Correspond : "<div>Bonjour</div>" (chaîne entière)

Paresseux (non-gourmand) : Correspond au minimum possible (ajoutez ? après le quantificateur)

<.*?>     → Correspond : "<div>" et "</div>" séparément
Gourmand Paresseux Description
* *? 0 ou plus (paresseux)
+ +? 1 ou plus (paresseux)
? ?? 0 ou 1 (paresseux)
{n,m} {n,m}? Entre n et m (paresseux)

Exemple :

Texte : "Bonjour" et "Monde"

  • ".*" correspond : "Bonjour" et "Monde" (gourmand)
  • ".*?" correspond : "Bonjour" et "Monde" séparément (paresseux)

Ancres et Limites

Les ancres correspondent à des positions, pas des caractères.

Pattern Description Exemple Correspond
^ Début de chaîne/ligne ^Bonjour "Bonjour Monde" (au début)
$ Fin de chaîne/ligne Monde$ "Bonjour Monde" (à la fin)
\b Limite de mot \bchat\b "chat" dans "Le chat noir" (PAS "achat")
\B Non-limite de mot \Bcha "achat" (cha PAS à la limite)
\A Début de chaîne (pas ligne) \ABonjour Correspond seulement si "Bonjour" est tout au début
\z Fin de chaîne (pas ligne) Monde\z Correspond seulement si "Monde" est tout à la fin
\Z Fin de chaîne (avant newline final) Monde\Z Correspond "Monde" ou "Monde\n"

Exemples :

^chat$        → Correspond : "chat" (la ligne entière est "chat")
\bchat\b      → Correspond : "chat" dans "le chat noir" (mot entier)
\Bcha         → Correspond : "cha" dans "achat" (PAS à la limite)

Mode Multiligne (flag m) :

  • Sans m : ^ et $ correspondent au début/fin de la chaîne entière
  • Avec m : ^ et $ correspondent au début/fin de chaque ligne

Groupes et Alternance

Groupes de Capture

Les groupes de capture (...) mémorisent le texte correspondant :

(\d+)-(\d+)   → Correspond : "123-456"
                Groupe 1 : "123"
                Groupe 2 : "456"

Références arrière (réutilise les groupes capturés) :

(\w)\1        → Correspond : "aa", "bb", "cc" (caractère répété)
(\w+) \1      → Correspond : "bonjour bonjour" (mot répété)

Groupes Non-Capturants

Utilisez (?:...) quand vous devez grouper mais n'avez pas besoin de capturer :

(?:https?://)  → Groupe "http://" ou "https://" sans capturer

Pourquoi utiliser non-capturant ?

  • Meilleures performances (pas de surcharge mémoire)
  • Références arrière plus propres (les groupes numérotés ne comptent que les groupes de capture)

Alternance (OU)

Utilisez | pour "correspond à ceci OU cela" :

chat|chien    → Correspond : "chat" ou "chien"
gr(i|a)s      → Correspond : "gris" ou "gras"

Exemples :

(M|Mme|Dr)\.?  → Correspond : "M.", "Mme", "Dr."
https?://      → Correspond : "http://" ou "https://"

Assertions Lookaround

Les lookaround sont des assertions de largeur nulle qui correspondent à une position (comme les ancres) mais avec des conditions.

Lookahead Positif (?=...)

Correspond si le pattern devant correspond (mais ne le consomme pas) :

\d(?=px)      → Correspond : "10" dans "10px" (PAS la partie "px")

Cas d'usage : Validation de mot de passe

^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$

Décomposition :

  • (?=.*[A-Z]) - Doit contenir une majuscule
  • (?=.*[a-z]) - Doit contenir une minuscule
  • (?=.*\d) - Doit contenir un chiffre
  • (?=.*[@$!%*?&]) - Doit contenir un caractère spécial
  • .{8,} - Au moins 8 caractères

Lookahead Négatif (?!...)

Correspond si le pattern devant NE correspond PAS :

\d(?!px)      → Correspond : "10" dans "10em" (PAS "10px")

Cas d'usage : Exclure certains mots

\b(?!test)\w+  → Correspond aux mots qui NE commencent PAS par "test"

Lookbehind Positif (?<=...)

Correspond si le pattern derrière correspond :

(?<=€)\d+     → Correspond : "100" dans "€100" (PAS la partie "€")

Cas d'usage : Extraire des prix

(?<=Prix : €)\d+,\d{2}  → Correspond : "29,99" dans "Prix : €29,99"

Lookbehind Négatif (?<!...)

Correspond si le pattern derrière NE correspond PAS :

(?<!€)\d+     → Correspond : "100" mais PAS dans "€100"

Tableau Récapitulatif :

Type Syntaxe Description Exemple
Lookahead Positif (?=...) Correspond si suivi de... q(?=u) correspond "q" dans "queen"
Lookahead Négatif (?!...) Correspond si PAS suivi de... q(?!u) correspond "q" dans "iraq"
Lookbehind Positif (?<=...) Correspond si précédé de... (?<=€)\d+ correspond "10" dans "€10"
Lookbehind Négatif (?<!...) Correspond si PAS précédé de... (?<!€)\d+ correspond "10" dans "10"

Groupes de Capture Nommés

Les groupes nommés (?<nom>...) rendent les regex plus lisibles :

JavaScript :

const dateRegex = /(?<annee>\d{4})-(?<mois>\d{2})-(?<jour>\d{2})/;
const match = '2025-01-17'.match(dateRegex);

console.log(match.groups.annee);   // "2025"
console.log(match.groups.mois);    // "01"
console.log(match.groups.jour);    // "17"

Python :

import re

pattern = r'(?P<annee>\d{4})-(?P<mois>\d{2})-(?P<jour>\d{2})'
match = re.search(pattern, '2025-01-17')

print(match.group('annee'))   # "2025"
print(match.group('mois'))    # "01"
print(match.group('jour'))    # "17"

C# :

var pattern = @"(?<annee>\d{4})-(?<mois>\d{2})-(?<jour>\d{2})";
var match = Regex.Match("2025-01-17", pattern);

Console.WriteLine(match.Groups["annee"].Value);   // "2025"

Groupes Atomiques et Quantificateurs Possessifs

Groupes Atomiques (?>...)

Une fois correspondu, le groupe ne fait pas de retour arrière. Empêche le retour arrière catastrophique :

(?>\d+)bar    → Correspond : "123bar" (rapide)

Sans groupe atomique :

\d+bar        → Essaie : "123bar", "12bar", "1bar" (lent en cas d'échec)

Quantificateurs Possessifs

Gourmand Possessif Description
* *+ 0 ou plus (pas de retour arrière)
+ ++ 1 ou plus (pas de retour arrière)
? ?+ 0 ou 1 (pas de retour arrière)

Cas d'usage : Empêcher le retour arrière catastrophique sur les patterns complexes.


Support Unicode

Les moteurs regex modernes supportent les catégories et scripts Unicode.

Catégories Unicode \p{...}

JavaScript (ES2018+) :

const letters = /\p{L}+/u;     // N'importe quelle lettre (n'importe quelle langue)
const numbers = /\p{N}+/u;     // N'importe quel nombre
const currency = /\p{Sc}/u;    // Symboles de devise

Python :

import regex  # Note : nécessite le module 'regex', pas 're'

letters = regex.compile(r'\p{L}+')

Catégories Unicode Courantes :

Catégorie Description Exemple
\p{L} Lettre "a", "字", "א"
\p{N} Nombre "1", "①", "一"
\p{S} Symbole "$", "©", "♥"
\p{Sc} Symbole devise "$", "€", "¥"
\p{P} Ponctuation ".", "!", "?"
\p{Z} Séparateur Espace, tabulation

Scripts Unicode :

/\p{Script=Greek}/u     → Correspond aux lettres grecques : "α", "β", "γ"
/\p{Script=Cyrillic}/u  → Correspond au cyrillique : "а", "б", "в"
/\p{Script=Han}/u       → Correspond aux caractères chinois

Négation :

/\P{L}+/u   → Correspond à tout ce qui N'est PAS une lettre

Modificateurs et Flags

Les flags changent la façon dont les patterns regex sont interprétés.

Flag Nom Description Exemple
i Insensible casse Ignore la casse /bonjour/i correspond "Bonjour"
g Global Trouve toutes les correspondances /chat/g trouve tous les "chat"
m Multiligne ^ et $ correspondent débuts/fins de ligne /^bonjour/m
s Dotall . correspond aussi aux newlines /a.b/s correspond "a\nb"
u Unicode Active les fonctionnalités Unicode /\p{L}+/u
x Étendu Ignore les espaces blancs (free-spacing) Permet les commentaires
y Sticky Correspond à une position exacte JavaScript uniquement

Exemples :

Insensible casse (i) :

/bonjour/i.test('BONJOUR')   // true

Global (g) :

'chat chien chat'.match(/chat/g)   // ["chat", "chat"]

Multiligne (m) :

const text = 'Ligne 1\nLigne 2';
/^Ligne 2/m.test(text)   // true (sans 'm' : false)

Dotall (s) :

/a.b/s.test('a\nb')   // true (sans 's' : false)

Modificateurs Inline

Appliquer les flags à une partie du pattern :

(?i)bonjour    → "bonjour" insensible casse
(?-i)MONDE     → "MONDE" sensible casse
(?i:bonjour)   → Seulement "bonjour" est insensible casse

Patterns Conditionnels

Syntaxe : (?(condition)vrai|faux)

Exemple : Correspondre aux chaînes entre guillemets ou non

("|')?[^"'\r\n]*(?(1)\1)

Décomposition :

  • ("|')? - Capture optionnellement un guillemet d'ouverture
  • [^"'\r\n]* - Correspond au contenu
  • (?(1)\1) - Si groupe 1 correspond (guillemet ouverture), correspond au même guillemet fermeture

Correspond :

  • "bonjour"
  • 'monde'
  • test ✅ (pas de guillemets)
  • "mixte' ❌ (guillemets non correspondants)

Commentaires dans les Regex

Commentaires Inline (?# commentaire)

\d{3}(?# indicatif)-\d{3}(?# central)-\d{4}(?# numéro)

Mode Free-Spacing (flag x)

Ignore les espaces blancs et permet les commentaires :

(?x)
  \d{3}     # indicatif
  -         # séparateur
  \d{3}     # central
  -         # séparateur
  \d{4}     # numéro

Beaucoup plus lisible pour les patterns complexes !

Cette section démontre comment utiliser les regex dans 7 langages de programmation populaires. Chaque langage a sa propre API regex, mais la syntaxe des patterns reste largement cohérente.

JavaScript / Node.js

Créer des Patterns Regex

// Notation littérale (la plus courante)
const pattern1 = /\d{3}-\d{4}/;

// Constructeur (quand le pattern est dynamique)
const pattern2 = new RegExp('\\d{3}-\\d{4}');
// Note : Les backslashes doivent être échappés dans les chaînes

// Avec flags
const pattern3 = /bonjour/gi;  // Global, insensible casse

Méthodes String

// .match() - Trouve les correspondances
const text = 'Contact : 06 12 34 56 78 ou 06 98 76 54 32';
const matches = text.match(/\d{2} \d{2} \d{2} \d{2} \d{2}/g);
console.log(matches);  // ["06 12 34 56 78", "06 98 76 54 32"]

// .matchAll() - Obtenir toutes les correspondances avec groupes (ES2020)
const emailPattern = /([\w.-]+)@([\w.-]+\.[a-z]{2,})/gi;
const emails = 'admin@exemple.fr, user@test.org';
for (const match of emails.matchAll(emailPattern)) {
  console.log(`Utilisateur : ${match[1]}, Domaine : ${match[2]}`);
}
// Utilisateur : admin, Domaine : exemple.fr
// Utilisateur : user, Domaine : test.org

// .search() - Trouve la position de la première correspondance
const pos = 'Bonjour Monde'.search(/Monde/);
console.log(pos);  // 8

// .replace() - Remplace les correspondances
const phone = '+33 6 12 34 56 78';
const cleaned = phone.replace(/[^\d]/g, '');
console.log(cleaned);  // "33612345678"

// .replaceAll() - Remplace toutes les correspondances (ES2021)
const text2 = 'chat chien chat';
const result = text2.replaceAll(/chat/g, 'oiseau');
console.log(result);  // "oiseau chien oiseau"

// .split() - Divise par pattern
const csv = 'pomme,banane, orange , raisin';
const fruits = csv.split(/\s*,\s*/);
console.log(fruits);  // ["pomme", "banane", "orange", "raisin"]

Méthodes RegExp

// .test() - Retourne un booléen
const isEmail = /^[\w.-]+@[\w.-]+\.[a-z]{2,}$/i;
console.log(isEmail.test('user@exemple.fr'));  // true

// .exec() - Retourne les détails de la correspondance (ou null)
const pattern = /(\d{4})-(\d{2})-(\d{2})/;
const match = pattern.exec('Date : 2025-01-17');
if (match) {
  console.log(match[0]);  // "2025-01-17" (correspondance complète)
  console.log(match[1]);  // "2025" (groupe 1)
  console.log(match[2]);  // "01" (groupe 2)
  console.log(match[3]);  // "17" (groupe 3)
}

Groupes Nommés (ES2018+)

const pattern = /(?<annee>\d{4})-(?<mois>\d{2})-(?<jour>\d{2})/;
const match = '2025-01-17'.match(pattern);

console.log(match.groups.annee);   // "2025"
console.log(match.groups.mois);    // "01"
console.log(match.groups.jour);    // "17"

// Références arrière nommées
const dupeWord = /\b(?<mot>\w+)\s+\k<mot>\b/i;
console.log(dupeWord.test('bonjour bonjour'));  // true

Support Unicode (ES2018+)

// Correspond à n'importe quelle lettre (incluant accentuées, chinoises, arabes, etc.)
const letters = /\p{L}+/u;
console.log(letters.test('café'));   // true
console.log(letters.test('你好'));   // true

// Correspond aux emojis
const emoji = /\p{Emoji}/u;
console.log(emoji.test('Bonjour 👋'));  // true

Python

Le Module re

import re

# Compiler le pattern (recommandé pour réutilisation)
pattern = re.compile(r'\d{2} \d{2} \d{2} \d{2} \d{2}')

# Ou utiliser directement
re.search(r'\d{2} \d{2} \d{2} \d{2} \d{2}', 'Appelez 06 12 34 56 78')

Fonctions Core

import re

# re.search() - Trouve la première correspondance
match = re.search(r'\d{2} \d{2} \d{2} \d{2} \d{2}', 'Contact : 06 12 34 56 78 ou 06 98 76 54 32')
if match:
    print(match.group())  # "06 12 34 56 78"
    print(match.start())  # 10 (position)
    print(match.end())    # 27

# re.match() - Correspond au DÉBUT de la chaîne
match = re.match(r'\d+', '123 rue de Rivoli')
print(match.group() if match else None)  # "123"

match = re.match(r'\d+', 'rue de Rivoli 123')
print(match)  # None (ne commence pas par un chiffre)

# re.fullmatch() - Correspond à la chaîne ENTIÈRE
result = re.fullmatch(r'\d{2} \d{2} \d{2} \d{2} \d{2}', '06 12 34 56 78')
print(bool(result))  # True

result = re.fullmatch(r'\d{2} \d{2} \d{2} \d{2} \d{2}', 'Appelez 06 12 34 56 78')
print(bool(result))  # False (texte supplémentaire)

# re.findall() - Trouve toutes les correspondances (retourne une liste)
text = 'Prix : €10, €25, €100'
prices = re.findall(r'€(\d+)', text)
print(prices)  # ['10', '25', '100']

# re.finditer() - Trouve toutes les correspondances (retourne un itérateur)
for match in re.finditer(r'€(\d+)', text):
    print(f'Trouvé €{match.group(1)} à la position {match.start()}')
# Trouvé €10 à la position 6
# Trouvé €25 à la position 11
# Trouvé €100 à la position 16

# re.sub() - Remplace les correspondances
phone = '+33 6 12 34 56 78'
cleaned = re.sub(r'[^\d]', '', phone)
print(cleaned)  # "33612345678"

# re.split() - Divise par pattern
csv = 'pomme,banane, orange , raisin'
fruits = re.split(r'\s*,\s*', csv)
print(fruits)  # ['pomme', 'banane', 'orange', 'raisin']

Groupes et Groupes Nommés

import re

# Groupes numérotés
pattern = r'(\d{4})-(\d{2})-(\d{2})'
match = re.search(pattern, 'Date : 2025-01-17')
if match:
    print(match.group(0))  # "2025-01-17" (correspondance complète)
    print(match.group(1))  # "2025"
    print(match.group(2))  # "01"
    print(match.group(3))  # "17"
    print(match.groups())  # ('2025', '01', '17')

# Groupes nommés (?P<nom>...)
pattern = r'(?P<annee>\d{4})-(?P<mois>\d{2})-(?P<jour>\d{2})'
match = re.search(pattern, '2025-01-17')
if match:
    print(match.group('annee'))   # "2025"
    print(match.group('mois'))    # "01"
    print(match.group('jour'))    # "17"
    print(match.groupdict())      # {'annee': '2025', 'mois': '01', 'jour': '17'}

Flags

import re

# Insensible casse
re.search(r'bonjour', 'BONJOUR', re.IGNORECASE)  # ou re.I

# Multiligne (^ et $ correspondent débuts/fins de ligne)
re.search(r'^Ligne 2', 'Ligne 1\nLigne 2', re.MULTILINE)  # ou re.M

# Dotall (. correspond newline)
re.search(r'a.b', 'a\nb', re.DOTALL)  # ou re.S

# Verbose (mode free-spacing avec commentaires)
pattern = re.compile(r'''
    \d{2}     # indicatif
    \s        # espace
    \d{2}     # paire 1
    \s        # espace
    \d{2}     # paire 2
    \s        # espace
    \d{2}     # paire 3
    \s        # espace
    \d{2}     # paire 4
''', re.VERBOSE)  # ou re.X

# Combiner les flags avec |
pattern = re.compile(r'bonjour', re.IGNORECASE | re.MULTILINE)

Remplacement avec Fonctions

import re

# Utiliser une fonction pour des remplacements dynamiques
def double_number(match):
    num = int(match.group())
    return str(num * 2)

text = "J'ai 5 pommes et 10 oranges"
result = re.sub(r'\d+', double_number, text)
print(result)  # "J'ai 10 pommes et 20 oranges"

# Avec des groupes nommés
def format_name(match):
    return f"{match.group('nom').upper()}, {match.group('prenom')}"

pattern = r'(?P<prenom>\w+)\s+(?P<nom>\w+)'
text = 'Jean Dupont'
result = re.sub(pattern, format_name, text)
print(result)  # "DUPONT, Jean"

PHP

Fonctions PCRE

<?php

// preg_match() - Trouve la première correspondance
$pattern = '/\d{2} \d{2} \d{2} \d{2} \d{2}/';
$text = 'Contact : 06 12 34 56 78 ou 06 98 76 54 32';

if (preg_match($pattern, $text, $matches)) {
    echo $matches[0];  // "06 12 34 56 78"
}

// preg_match_all() - Trouve toutes les correspondances
preg_match_all('/\d{2} \d{2} \d{2} \d{2} \d{2}/', $text, $matches);
print_r($matches[0]);  // ["06 12 34 56 78", "06 98 76 54 32"]

// preg_replace() - Remplace les correspondances
$phone = '+33 6 12 34 56 78';
$cleaned = preg_replace('/[^\d]/', '', $phone);
echo $cleaned;  // "33612345678"

// preg_split() - Divise par pattern
$csv = 'pomme,banane, orange , raisin';
$fruits = preg_split('/\s*,\s*/', $csv);
print_r($fruits);  // ["pomme", "banane", "orange", "raisin"]

// preg_grep() - Filtre un tableau par pattern
$words = ['pomme', 'banane', 'abricot', 'orange'];
$aWords = preg_grep('/^a/', $words);
print_r($aWords);  // ["abricot"]
?>

Groupes Nommés

<?php
$pattern = '/(?P<annee>\d{4})-(?P<mois>\d{2})-(?P<jour>\d{2})/';
$text = '2025-01-17';

if (preg_match($pattern, $text, $matches)) {
    echo $matches['annee'];   // "2025"
    echo $matches['mois'];    // "01"
    echo $matches['jour'];    // "17"
}
?>

Modificateurs (Flags)

<?php
// i - Insensible casse
preg_match('/bonjour/i', 'BONJOUR');  // Correspond

// m - Multiligne
preg_match('/^Ligne 2/m', "Ligne 1\nLigne 2");  // Correspond

// s - Dotall (. correspond newline)
preg_match('/a.b/s', "a\nb");  // Correspond

// x - Free-spacing (ignore espaces blancs)
$pattern = '/
    \d{2}     # indicatif
    \s        # espace
    \d{2}     # paire 1
    \s        # espace
    \d{2}     # paire 2
/x';

// u - Support UTF-8
preg_match('/\w+/u', 'café');  // Correspond (inclut é)

// Combiner les modificateurs
preg_match('/bonjour/imu', $text);
?>

Remplacement avec Callback

<?php
$text = "J'ai 5 pommes et 10 oranges";

$result = preg_replace_callback('/\d+/', function($matches) {
    return (int)$matches[0] * 2;
}, $text);

echo $result;  // "J'ai 10 pommes et 20 oranges"
?>

C# (.NET)

Classe Regex

using System;
using System.Text.RegularExpressions;

// Méthodes statiques (utilisation simple)
string text = "Contact : 06 12 34 56 78 ou 06 98 76 54 32";
Match match = Regex.Match(text, @"\d{2} \d{2} \d{2} \d{2} \d{2}");
if (match.Success)
{
    Console.WriteLine(match.Value);  // "06 12 34 56 78"
}

// Trouve toutes les correspondances
MatchCollection matches = Regex.Matches(text, @"\d{2} \d{2} \d{2} \d{2} \d{2}");
foreach (Match m in matches)
{
    Console.WriteLine(m.Value);
}
// Sortie :
// 06 12 34 56 78
// 06 98 76 54 32

// Remplace
string phone = "+33 6 12 34 56 78";
string cleaned = Regex.Replace(phone, @"[^\d]", "");
Console.WriteLine(cleaned);  // "33612345678"

// Divise
string csv = "pomme,banane, orange , raisin";
string[] fruits = Regex.Split(csv, @"\s*,\s*");
// ["pomme", "banane", "orange", "raisin"]

Regex Compilée (Meilleures Performances)

using System.Text.RegularExpressions;

// Compiler pour réutilisation (beaucoup plus rapide pour utilisation répétée)
Regex pattern = new Regex(@"\d{2} \d{2} \d{2} \d{2} \d{2}", RegexOptions.Compiled);

string text = "Contact : 06 12 34 56 78";
Match match = pattern.Match(text);
if (match.Success)
{
    Console.WriteLine(match.Value);
}

RegexOptions (Flags)

using System.Text.RegularExpressions;

// Insensible casse
Regex.IsMatch("BONJOUR", "bonjour", RegexOptions.IgnoreCase);

// Multiligne
Regex.Match("Ligne 1\nLigne 2", "^Ligne 2", RegexOptions.Multiline);

// Singleline (. correspond newline)
Regex.Match("a\nb", "a.b", RegexOptions.Singleline);

// Compilée (meilleures performances)
var pattern = new Regex(@"\d+", RegexOptions.Compiled);

// Combiner les options
var opts = RegexOptions.IgnoreCase | RegexOptions.Multiline;
Regex.Match(text, pattern, opts);

Groupes Nommés

using System;
using System.Text.RegularExpressions;

string pattern = @"(?<annee>\d{4})-(?<mois>\d{2})-(?<jour>\d{2})";
Match match = Regex.Match("2025-01-17", pattern);

if (match.Success)
{
    Console.WriteLine(match.Groups["annee"].Value);   // "2025"
    Console.WriteLine(match.Groups["mois"].Value);    // "01"
    Console.WriteLine(match.Groups["jour"].Value);    // "17"
}

Remplacement avec MatchEvaluator

using System;
using System.Text.RegularExpressions;

string text = "J'ai 5 pommes et 10 oranges";

string result = Regex.Replace(text, @"\d+", match =>
{
    int num = int.Parse(match.Value);
    return (num * 2).ToString();
});

Console.WriteLine(result);  // "J'ai 10 pommes et 20 oranges"

Java

Classes Pattern et Matcher

import java.util.regex.Pattern;
import java.util.regex.Matcher;

// Compiler le pattern
Pattern pattern = Pattern.compile("\\d{2} \\d{2} \\d{2} \\d{2} \\d{2}");
String text = "Contact : 06 12 34 56 78 ou 06 98 76 54 32";

// Créer le matcher
Matcher matcher = pattern.matcher(text);

// Trouve la première correspondance
if (matcher.find()) {
    System.out.println(matcher.group());  // "06 12 34 56 78"
}

// Trouve toutes les correspondances
matcher.reset();  // Réinitialise au début
while (matcher.find()) {
    System.out.println(matcher.group());
}
// Sortie :
// 06 12 34 56 78
// 06 98 76 54 32

Méthodes String

// matches() - Vérifie si la chaîne ENTIÈRE correspond
boolean isPhone = "06 12 34 56 78".matches("\\d{2} \\d{2} \\d{2} \\d{2} \\d{2}");
System.out.println(isPhone);  // true

// replaceAll() - Remplace toutes les correspondances
String phone = "+33 6 12 34 56 78";
String cleaned = phone.replaceAll("[^\\d]", "");
System.out.println(cleaned);  // "33612345678"

// replaceFirst() - Remplace la première correspondance
String text = "chat chien chat";
String result = text.replaceFirst("chat", "oiseau");
System.out.println(result);  // "oiseau chien chat"

// split() - Divise par pattern
String csv = "pomme,banane, orange , raisin";
String[] fruits = csv.split("\\s*,\\s*");
// ["pomme", "banane", "orange", "raisin"]

Flags Pattern

import java.util.regex.Pattern;

// Insensible casse
Pattern pattern = Pattern.compile("bonjour", Pattern.CASE_INSENSITIVE);

// Multiligne
Pattern.compile("^Ligne 2", Pattern.MULTILINE);

// Dotall (. correspond newline)
Pattern.compile("a.b", Pattern.DOTALL);

// Commentaires (free-spacing)
Pattern.compile("""
    \\d{2}     # indicatif
    \\s        # espace
    \\d{2}     # paire 1
    """, Pattern.COMMENTS);

// Combiner les flags
int flags = Pattern.CASE_INSENSITIVE | Pattern.MULTILINE;
Pattern.compile("pattern", flags);

Groupes Nommés

import java.util.regex.Pattern;
import java.util.regex.Matcher;

Pattern pattern = Pattern.compile("(?<annee>\\d{4})-(?<mois>\\d{2})-(?<jour>\\d{2})");
Matcher matcher = pattern.matcher("2025-01-17");

if (matcher.find()) {
    System.out.println(matcher.group("annee"));   // "2025"
    System.out.println(matcher.group("mois"));    // "01"
    System.out.println(matcher.group("jour"));    // "17"
}

Remplacement Avancé

import java.util.regex.Pattern;
import java.util.regex.Matcher;

String text = "J'ai 5 pommes et 10 oranges";
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(text);

StringBuffer result = new StringBuffer();
while (matcher.find()) {
    int num = Integer.parseInt(matcher.group());
    matcher.appendReplacement(result, String.valueOf(num * 2));
}
matcher.appendTail(result);

System.out.println(result);  // "J'ai 10 pommes et 20 oranges"

Go (Golang)

Le Package regexp

package main

import (
    "fmt"
    "regexp"
)

func main() {
    // Compiler le pattern
    pattern := regexp.MustCompile(`\d{2} \d{2} \d{2} \d{2} \d{2}`)
    text := "Contact : 06 12 34 56 78 ou 06 98 76 54 32"

    // Trouve la première correspondance
    match := pattern.FindString(text)
    fmt.Println(match)  // "06 12 34 56 78"

    // Trouve toutes les correspondances
    matches := pattern.FindAllString(text, -1)
    fmt.Println(matches)  // [06 12 34 56 78 06 98 76 54 32]

    // Vérifie si correspond
    isMatch := pattern.MatchString("06 12 34 56 78")
    fmt.Println(isMatch)  // true

    // Remplace tout
    phone := "+33 6 12 34 56 78"
    cleaned := regexp.MustCompile(`[^\d]`).ReplaceAllString(phone, "")
    fmt.Println(cleaned)  // "33612345678"

    // Divise
    csv := "pomme,banane, orange , raisin"
    fruits := regexp.MustCompile(`\s*,\s*`).Split(csv, -1)
    fmt.Println(fruits)  // [pomme banane orange raisin]
}

Submatch (Groupes)

package main

import (
    "fmt"
    "regexp"
)

func main() {
    pattern := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)
    text := "Date : 2025-01-17"

    // FindStringSubmatch retourne [complet, groupe1, groupe2, ...]
    matches := pattern.FindStringSubmatch(text)
    if matches != nil {
        fmt.Println(matches[0])  // "2025-01-17" (correspondance complète)
        fmt.Println(matches[1])  // "2025" (groupe 1)
        fmt.Println(matches[2])  // "01" (groupe 2)
        fmt.Println(matches[3])  // "17" (groupe 3)
    }

    // FindAllStringSubmatch pour toutes les correspondances
    text2 := "Dates : 2025-01-17 et 2024-12-31"
    allMatches := pattern.FindAllStringSubmatch(text2, -1)
    for _, match := range allMatches {
        fmt.Printf("Année : %s, Mois : %s, Jour : %s\n", match[1], match[2], match[3])
    }
    // Année : 2025, Mois : 01, Jour : 17
    // Année : 2024, Mois : 12, Jour : 31
}

Groupes Nommés

package main

import (
    "fmt"
    "regexp"
)

func main() {
    pattern := regexp.MustCompile(`(?P<annee>\d{4})-(?P<mois>\d{2})-(?P<jour>\d{2})`)
    text := "2025-01-17"

    match := pattern.FindStringSubmatch(text)
    if match != nil {
        // Obtenir les indices des groupes nommés
        names := pattern.SubexpNames()
        result := make(map[string]string)
        for i, name := range names {
            if i != 0 && name != "" {
                result[name] = match[i]
            }
        }
        fmt.Println(result["annee"])   // "2025"
        fmt.Println(result["mois"])    // "01"
        fmt.Println(result["jour"])    // "17"
    }
}

Remplacement avec Fonctions

package main

import (
    "fmt"
    "regexp"
    "strconv"
)

func main() {
    text := "J'ai 5 pommes et 10 oranges"
    pattern := regexp.MustCompile(`\d+`)

    result := pattern.ReplaceAllStringFunc(text, func(s string) string {
        num, _ := strconv.Atoi(s)
        return strconv.Itoa(num * 2)
    })

    fmt.Println(result)  // "J'ai 10 pommes et 20 oranges"
}

Ruby

Littéraux Regex

# Notation littérale
pattern = /\d{2} \d{2} \d{2} \d{2} \d{2}/

# Avec flags
pattern_ci = /bonjour/i  # Insensible casse
pattern_multi = /^ligne/m  # Multiligne

# Constructeur (pour patterns dynamiques)
pattern = Regex.new('\d{2} \d{2} \d{2} \d{2} \d{2}')

Méthodes String

text = 'Contact : 06 12 34 56 78 ou 06 98 76 54 32'

# match() - Retourne MatchData ou nil
match = text.match(/\d{2} \d{2} \d{2} \d{2} \d{2}/)
if match
  puts match[0]  # "06 12 34 56 78"
end

# scan() - Trouve toutes les correspondances
matches = text.scan(/\d{2} \d{2} \d{2} \d{2} \d{2}/)
puts matches  # ["06 12 34 56 78", "06 98 76 54 32"]

# =~ opérateur - Retourne l'index de la première correspondance
index = text =~ /\d{2} \d{2} \d{2} \d{2} \d{2}/
puts index  # 10

# sub() - Remplace la première correspondance
result = 'chat chien chat'.sub(/chat/, 'oiseau')
puts result  # "oiseau chien chat"

# gsub() - Remplace toutes les correspondances
phone = '+33 6 12 34 56 78'
cleaned = phone.gsub(/[^\d]/, '')
puts cleaned  # "33612345678"

# split() - Divise par pattern
csv = 'pomme,banane, orange , raisin'
fruits = csv.split(/\s*,\s*/)
puts fruits  # ["pomme", "banane", "orange", "raisin"]

Groupes de Capture

pattern = /(\d{4})-(\d{2})-(\d{2})/
match = '2025-01-17'.match(pattern)

if match
  puts match[0]  # "2025-01-17" (correspondance complète)
  puts match[1]  # "2025" (groupe 1)
  puts match[2]  # "01" (groupe 2)
  puts match[3]  # "17" (groupe 3)
end

Groupes Nommés

pattern = /(?<annee>\d{4})-(?<mois>\d{2})-(?<jour>\d{2})/
match = '2025-01-17'.match(pattern)

if match
  puts match[:annee]   # "2025"
  puts match[:mois]    # "01"
  puts match[:jour]    # "17"
end

Remplacement avec Blocs

text = "J'ai 5 pommes et 10 oranges"

result = text.gsub(/\d+/) { |num| (num.to_i * 2).to_s }
puts result  # "J'ai 10 pommes et 20 oranges"

# Avec des groupes nommés
pattern = /(?<prenom>\w+)\s+(?<nom>\w+)/
text = 'Jean Dupont'

result = text.gsub(pattern) do |match|
  m = Regexp.last_match
  "#{m[:nom].upcase}, #{m[:prenom]}"
end
puts result  # "DUPONT, Jean"

Flags

# i - Insensible casse
/bonjour/i.match('BONJOUR')  # Correspond

# m - Multiligne (. correspond newline)
/a.b/m.match("a\nb")  # Correspond

# x - Free-spacing (ignore espaces blancs)
pattern = /
  \d{2}     # indicatif
  \s        # espace
  \d{2}     # paire 1
  \s        # espace
  \d{2}     # paire 2
/x

# o - Compiler une fois (optimisation)
pattern = /\d+/o

La fonction Rechercher et Remplacer de Visual Studio Code (Ctrl/Cmd+H) prend en charge les regex avec de puissantes capacités de transformation. Cette section présente 28 exemples pratiques que les développeurs utilisent quotidiennement.

Accéder à Rechercher et Remplacer

Raccourcis Clavier :

  • Rechercher : Ctrl+F (Windows/Linux) / Cmd+F (Mac)
  • Remplacer : Ctrl+H (Windows/Linux) / Cmd+H (Mac)
  • Activer Regex : Cliquez sur le bouton .* ou appuyez sur Alt+R

Astuces :

  • Utilisez Ctrl+Enter (Cmd+Enter) pour tout remplacer
  • Prévisualisez les correspondances avant de remplacer (elles sont surlignées en jaune)
  • Utilisez F3 / Shift+F3 pour naviguer entre les correspondances

Transformations Majuscules/Minuscules

VS Code prend en charge des séquences spéciales de remplacement pour la conversion de casse :

Séquence Effet Exemple
\l Minuscule caractère suivant \l
\u Majuscule caractère suivant \u
\L Minuscule tous les caractères suivants \L
\U Majuscule tous les caractères suivants \U
\E Termine la transformation de casse \U\E

Exemple 1 : Capitaliser Première Lettre

Rechercher :

\b(\w)(\w*)

Remplacer :

\u$1$2

Avant :

bonjour monde

Après :

Bonjour Monde

Cette section fournit plus de 25 patterns regex prêts à l'emploi.

Validation Email

^[\w.-]+@[\w.-]+\.[a-z]{2,}$

Numéros de Téléphone (France)

^(\+?33|0)[-.\s]?([1-9])[-.\s]?(\d{2})[-.\s]?(\d{2})[-.\s]?(\d{2})[-.\s]?(\d{2})$

Dates (ISO 8601)

^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$

URL

^https?://(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b

Adresses IPv4

^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$

Couleurs Hex

^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$

Mot de Passe Fort

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$

Nom d'Utilisateur (3-16 caractères)

^[a-zA-Z0-9_-]{3,16}$

UUID v4

^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$

Et plus de 15 autres patterns avec documentation complète !

Applications regex du monde réel dans le développement.

Validation de Formulaire

const validators = {
  email: /^[\w.-]+@[\w.-]+\.[a-z]{2,}$/i,
  phone: /^(\+?33|0)[1-9](\d{2}){4}$/
};

Extraction de Données

Extraire des emails du texte :

import re
emails = re.findall(r'[\w.-]+@[\w.-]+\.[a-z]{2,}', text)

Analyse de Logs

pattern = r'(?P<ip>[\d.]+).+(?P<status>\d{3})'

Refactoring de Code

Convertir d'anciennes appels API dans VS Code :

Rechercher : apiClient\.get\('([^']+)'\)
Remplacer : fetch('$1').then(r => r.json())

Erreurs Courantes

1. Oublier d'Échapper les Caractères Spéciaux

❌ Incorrect : fichier.txt
✅ Correct : fichier\.txt

2. Gourmand vs Paresseux

❌ Gourmand : <.*> correspond à l'ensemble <div>texte</div>
✅ Paresseux : <.*?> correspond à <div> et </div> séparément

3. Ne Pas Utiliser d'Ancres

/\d{3}/ correspond à "123" dans "abc123def"
/^\d{3}$/ correspond uniquement à exactement "123"

Conseils de Performance

  1. Utilisez des classes de caractères spécifiques au lieu de .
  2. Ancrez les patterns quand c'est possible
  3. Évitez les quantificateurs imbriqués (retour arrière catastrophique)
  4. Utilisez des groupes atomiques pour les performances
  5. Compilez les patterns pour la réutilisation

Débogage

  1. Testez sur regex101.com
  2. Utilisez le mode verbose avec commentaires
  3. Divisez les patterns complexes en parties
  4. Testez les cas limites

Outils en Ligne

Testeurs Regex

  • regex101.com - Meilleur testeur avec explications
  • regexr.com - Constructeur visuel de regex
  • regexpal.com - Test simple et rapide

Visualiseurs

  • debuggex.com - Diagrammes railroad
  • regexper.com - Outil visuel

Ressources d'Apprentissage

  • regexone.com - Leçons interactives
  • regexlearn.com - Guide pas à pas
  • regular-expressions.info - Documentation

Extensions IDE

  • Regex Previewer (VS Code)
  • Regex Tester (VS Code)

Classes de Caractères

Pattern Correspond
\d Chiffre [0-9]
\w Mot [a-zA-Z0-9_]
\s Espace blanc
. N'importe quel caractère

Quantificateurs

Pattern Signification
* 0 ou plus
+ 1 ou plus
? 0 ou 1
{n} Exactement n

Ancres

Pattern Signification
^ Début ligne
$ Fin ligne
\b Limite mot

Flags

Flag Signification
i Insensible casse
g Global
m Multiligne
s Dotall

Questions Générales

Q : Quelle est la différence entre les quantificateurs gourmands et paresseux ?

R : Gourmand correspond au maximum possible. Paresseux (*?, +?) correspond au minimum possible.

Q : Comment correspondre à un point littéral ?

R : Échappez-le avec un backslash : \.

Q : Qu'est-ce que le retour arrière catastrophique ?

R : Quand la regex essaie de nombreuses combinaisons, causant de la lenteur. Évitez les quantificateurs imbriqués comme (a+)+.

Q : Les regex peuvent-elles valider parfaitement un email ?

R : Non. Utilisez regex pour le format de base, puis vérifiez via email.

Q : Comment correspondre sur plusieurs lignes ?

R : Utilisez le flag s, ou utilisez [\s\S]* au lieu de .*.

Spécifique VS Code

Q : Comment remplacer avec majuscules dans VS Code ?

R : Utilisez \u (majuscule suivante), \U (majuscule tout).

Q : Puis-je utiliser regex dans la recherche de fichiers de VS Code ?

R : Oui ! Appuyez sur Ctrl+Shift+F et activez regex (Alt+R).

Extension Chrome Regex Data Extractor

Notre Regex Data Extractor vous aide à extraire des données de pages web en utilisant les patterns de ce guide.

Fonctionnalités Clés

  • Bibliothèque de Patterns : Patterns pré-construits
  • Test en Temps Réel : Testez les regex sur n'importe quelle page web
  • Export Multi-Format : CSV, JSON, Excel, PDF
  • Extraction par Lot : Extrayez de plusieurs pages

Exemple : Extraire des Emails

  1. Installez Regex Data Extractor
  2. Naviguez sur n'importe quelle page web
  3. Cliquez sur l'icône de l'extension
  4. Entrez le pattern : [\w.-]+@[\w.-]+\.[a-z]{2,}
  5. Cliquez sur "Extraire"
  6. Exportez en CSV/JSON

Exemple : Extraire des Prix

Pattern : €([0-9]{1,3}(?:\s?[0-9]{3})*,?[0-9]{2})
Capture : €1 234,56, €99,99

Astuces Pro

  • Sauvegardez les patterns fréquemment utilisés
  • Utilisez des groupes nommés pour des données structurées
  • Testez d'abord les patterns
  • Exportez pour l'analyse de données

Obtenir Regex Data Extractor →

regexexpressions régulièresaide-mémoirepatterntutorielvs codepythonjavascriptphp

Last updated: 16 janvier 2025