Apprendre les Expressions Régulières (Regex)

Apprendre les expressions régulières (regex) pour catégoriser des données et extraire des informations.

1. Qu'est-ce qu'une expression régulière ?

Une expression régulière est une séquence de caractères qui définit un motif de recherche. Ce motif est ensuite utilisé pour trouver des correspondances dans des chaînes de caractères. Pensez-y comme à une version très avancée de la fonction "Rechercher" (Ctrl+F) que vous utilisez tous les jours.

Les regex sont souvent utilisées pour valider des champs (ex: vérifier qu'une adresse e-mail est valide), extraire des informations d'une URL (ex: récupérer l'ID d'un produit), ou encore catégoriser des URLs en SEO.

Par exemple :

  • Vérifier si une chaîne est une adresse e-mail valide : ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
  • Extraire l'ID d'un produit dans une URL type /product/12345/details : /product/(\d+)/
  • Catégoriser des URLs en SEO (ex: différencier les pages catégories des pages produits)

Les regex sont utilisées dans une multitude de tâches liées au texte :

  • Filtrage : Sélectionner des lignes ou des données qui correspondent à un certain format (ex: trouver toutes les lignes contenant une adresse email dans un fichier log).
  • Validation : Vérifier si une entrée utilisateur respecte un format spécifique (ex: un numéro de téléphone, un code postal, une adresse email).
  • Couteau suisse pour l'extraction : Extraire l'ID d'un produit dans une URL type /product/12345/details : /product/(\d+)/
  • Catégoriser des URLs en SEO : Différencier les pages catégories des pages produits par exemple

  • Remplacement : Trouver toutes les occurrences d'un motif et les remplacer par autre chose (ex: anonymiser des noms dans un document).

Pourquoi c'est un outil puissant ?

  • Concises : Elles permettent d'exprimer des règles de recherche complexes en peu de caractères.
  • Polyvalentes : Elles sont intégrées dans de nombreux langages de programmation, éditeurs de texte, et outils d'analyse.
  • Efficaces : Une fois maîtrisées, elles font gagner un temps considérable pour des tâches de manipulation de texte répétitives ou complexes.

Les bases des Regex

Les regex sont construites à partir de caractères normaux et de caractères spéciaux appelés métacaractères, qui ont une signification particulière.

Symbole Description Exemple Regex Texte d'exemple Match
. N'importe quel caractère (sauf retour à la ligne) c.t cat, cot, czt cat, cot, czt
* 0 ou plusieurs fois le caractère précédent ca*t ct, cat, caaat ct, cat, caaat
+ 1 ou plusieurs fois le caractère précédent ca+t ct, cat, caaat cat, caaat
? 0 ou 1 fois le caractère précédent (optionnel) colou?r color, colour color, colour
^ Début de la chaîne (ou de ligne en mode multi-lignes) ^Hello Hello world Hello
$ Fin de la chaîne (ou de ligne en mode multi-lignes) world$ Hello world world
\ Caractère d'échappement (pour utiliser un métacaractère littéralement) \.com site.com .com

Classes de Caractères

Elles permettent de définir des ensembles de caractères possibles.

Symbole Description Exemple Regex Texte d'exemple Match
\d N'importe quel chiffre (équivalent à [0-9]) \d{3} abc123xyz 123
\D N'importe quel caractère qui N'EST PAS un chiffre \D+ 123-ABC-456 -ABC-
\w Caractère alphanumérique (lettre, chiffre, ) (équivalent à `[a-zA-Z0-9]`) \w+ Hello_123! Hello_123
\W Caractère NON alphanumérique \W Hello_123! !
\s Espace blanc (espace, tabulation, retour ligne) Hello\sWorld Hello World Hello World
\S Caractère NON espace blanc \S+ Hello World Hello, World
[abc] L'un des caractères spécifiés (a, b, ou c) gr[ae]y gray, grey gray, grey
[^abc] N'importe quel caractère SAUF a, b, ou c [^0-9] Var_1 V, a, r, _
[a-z] N'importe quelle lettre minuscule entre a et z [a-z]+ Hello World ello, orld
[A-Z0-9] N'importe quelle lettre majuscule OU chiffre [A-Z0-9]{2} ID: AB12 AB, 12

Quantificateurs

Ils spécifient combien de fois un caractère, un groupe ou une classe de caractères doit apparaître.

Symbole Description Exemple Regex Texte d'exemple Match
* 0 ou plusieurs fois bo*m bm, bom, boom bm, bom, boom
+ 1 ou plusieurs fois bo+m bm, bom, boom bom, boom
? 0 ou 1 fois honou?r honor, honour honor, honour
{n} Exactement n fois \d{4} Code: 12345 1234
{n,} Au moins n fois \d{2,} 1, 12, 123 12, 123
{n,m} Entre n et m fois (inclus) a{2,4} a, aa, aaa, aaaa, aaaaa aa, aaa, aaaa

Exemples et explications

  • ^Bonjour : correspond aux phrases qui commencent par "Bonjour"
  • \d{4} : correspond à une séquence de quatre chiffres, utile pour détecter une année
  • a.*z : capture tout texte commençant par "a" et finissant par "z"
Bonne pratique : Testez vos regex ! Utilisez des outils en ligne comme regex101.com, regexr.com ou les fonctionnalités intégrées de votre éditeur (VS Code, etc.) pour visualiser et déboguer vos motifs.

Les Regex intermédiaires

Une fois les bases acquises, on peut commencer à construire des regex plus complexes et ciblées.

Groupes de capture ()

Les parenthèses () ont deux fonctions principales :

  1. Grouper des parties de la regex pour leur appliquer un quantificateur.
    • Exemple : (ab)+ cherchera une ou plusieurs répétitions de la séquence "ab" (ab, abab, ababab...). Sans les parenthèses, ab+ chercherait "a" suivi de une ou plusieurs répétitions de "b" (ab, abb, abbb...).
  2. Capturer le texte qui correspond à la partie de la regex entre parenthèses. Ces captures peuvent être réutilisées.

Backreferences \1, \2...

Une fois qu'un groupe a capturé du texte, vous pouvez faire référence à ce texte capturé plus loin dans la même regex en utilisant \1 pour le premier groupe capturant, \2 pour le deuxième, etc.

  • Exemple : Trouver des mots répétés
    • Regex : (\b\w+\b)\s+\1
    • Texte : Ceci est est un test test.
    • Correspondances : est est, test test
    • Explication :
      • \b\w+\b : Trouve un mot complet (\b = frontière de mot).
      • (...) : Capture ce mot (groupe 1).
      • \s+ : Cherche un ou plusieurs espaces.
      • \1 : Cherche exactement le même texte que celui capturé par le groupe 1.

Alternances |

Le symbole | agit comme un "OU". Il permet de chercher l'une ou l'autre des expressions qu'il sépare.

  • Exemple : Chercher "chat" ou "chien"
    • Regex : chat|chien
    • Texte : J'ai un chat et un chien.
    • Correspondances : chat, chien
  • Exemple avec groupe : Chercher "le chat" ou "le chien"
    • Regex : le (chat|chien)
    • Texte : J'ai vu le chat puis le chien.
    • Correspondances : le chat (capture "chat"), le chien (capture "chien")

Exemple d'utilisation avancée : Extraction de données

Supposons que vous ayez un texte avec des informations structurées comme "Nom: Dupont, Age: 42". Vous voulez extraire le nom et l'âge.

  • Regex : Nom: (\w+), Age: (\d+)
  • Texte : Nom: Dupont, Age: 42
  • Correspondance complète : Nom: Dupont, Age: 42
  • Capture groupe 1 (\1) : Dupont
  • Capture groupe 2 (\2) : 42
Les groupes non-capturants (?:...) permettent de grouper sans créer de backreference. Utile quand vous avez besoin de grouper pour un quantificateur mais que vous ne voulez pas "consommer" un numéro de capture.

Les Regex avancées

Ces concepts sont plus complexes mais débloquent des possibilités très puissantes.

Lookahead et Lookbehind (Assertions avant et arrière)

Ce sont des assertions de largeur nulle ("zero-width assertions"). Elles vérifient la présence (ou l'absence) de motifs avant ou après la position actuelle, sans consommer de caractères (c'est-à-dire sans faire partie de la correspondance finale).

Type Syntaxe Description Exemple Regex Texte Correspondance Explication
Lookahead Positif (?=...) Vérifie que ce qui suit correspond au motif ... \d+(?=€) 100€, 50$ 100 Trouve les nombres suivis du symbole €
Lookahead Négatif (?!...) Vérifie que ce qui suit NE correspond PAS au motif ... q(?!u) quit, seq q (dans seq) Trouve un q non suivi d'un u
Lookbehind Positif (?<=...) Vérifie que ce qui précède correspond au motif ... (?<=M\.)\s+\w+ M. Dupont Dupont Trouve le nom (\w+) précédé de M.
Lookbehind Négatif (?<!...) Vérifie que ce qui précède NE correspond PAS au motif ... (?<!Mr|Mme)\s+Dupont M. Dupont Dupont Trouve Dupont non précédé de Mr ou Mme
Les lookbehinds sont plus limités que les lookaheads dans certains moteurs de regex (ils doivent souvent avoir une longueur fixe). Vérifiez la documentation de votre outil/langage.

Greedy (Gourmand) et Lazy (Paresseux) Matching

Par défaut, les quantificateurs *, +, {n,} sont gourmands : ils essaient de correspondre au plus grand nombre de caractères possible.

  • Exemple Greedy :
    • Regex : <.*>
    • Texte : Ce texte contient <h1>Titre</h1> et <p>Paragraphe</p>.
    • Correspondance : <h1>Titre</h1> et <p>Paragraphe</p> (il prend tout depuis le premier < jusqu'au dernier >)

Pour rendre un quantificateur paresseux (correspondre au plus petit nombre de caractères possible), ajoutez un ? après lui (*?, +?, {n,}?, {n,m}?).

  • Exemple Lazy :
    • Regex : <.*?>
    • Texte : Ce texte contient <h1>Titre</h1> et <p>Paragraphe</p>.
    • Correspondances : <h1>, </h1>, <p>, </p> (il s'arrête au premier > rencontré)
Soyez explicite ! Si vous voulez capturer le contenu d'une balise HTML, préférez `‹h1›(.*?)‹/h1›` (lazy) à `‹h1›.*‹/h1›` (greedy) pour éviter les surprises. Pour du HTML/XML, des parseurs dédiés sont souvent plus robustes.

Regex multi-lignes et flags (modificateurs)

Les "flags" (ou modificateurs) changent le comportement global de la regex. Ils sont généralement spécifiés en dehors du motif lui-même (voir section 6).

  • m (multi-lignes) : ^ et $ correspondent au début/fin de chaque ligne, en plus du début/fin de la chaîne entière.
  • i (insensible à la casse) : Ignore la différence entre majuscules et minuscules (a correspond à a et A).
  • g (global) : Trouve toutes les correspondances, pas seulement la première. (Souvent un paramètre de fonction plutôt qu'un flag de la regex elle-même).
  • s (single line / dotall) : Le métacaractère . correspond aussi aux caractères de retour à la ligne (\n). Utile pour des correspondances qui s'étendent sur plusieurs lignes.

Cas d'usage avancés

  • Data Scraping : Extraire des données spécifiques (prix, noms de produits, emails) de pages web.
  • Validation de Formulaires : Créer des règles complexes pour valider des numéros de téléphone internationaux, des mots de passe sécurisés, etc.
  • Analyse de Logs : Isoler des erreurs spécifiques, extraire des adresses IP, suivre des sessions utilisateur dans des fichiers logs volumineux.
  • Refactoring de Code : Effectuer des remplacements complexes dans une base de code.

Où utiliser les Regex ?

La beauté des regex est leur omniprésence :

  • Tableurs :
    • Google Sheets : Fonctions REGEXMATCH, REGEXEXTRACT, REGEXREPLACE.
    • Microsoft Excel : Via des fonctions VBA ou des compléments. Moins natif que Google Sheets.
  • Outils de Crawl SEO :
    • Screaming Frog : Filtres personnalisés pour inclure/exclure des URLs, recherche de code source, extraction personnalisée.
    • Botify : Segmentation avancée des URLs, analyse de logs serveur.
  • Langages de Programmation :
    • Python : Module re (re.search, re.match, re.findall, re.sub).
    • JavaScript : Objet RegExp et méthodes de String (match, search, replace, split).
    • PHP : Fonctions preg_* (preg_match, preg_match_all, preg_replace).
    • Java : Package java.util.regex (Pattern, Matcher).
    • ... et bien d'autres (Perl, Ruby, C#, Go...).
  • Éditeurs de Texte et IDEs :
    • VS Code : Fonctionnalité de recherche et remplacement (Ctrl+F / Ctrl+H) avec option Regex.
    • Sublime Text, Atom, Notepad++, etc. : Idem, la recherche/remplacement basée sur regex est standard.
  • Ligne de commande (Linux/macOS) :
    • grep, sed, awk utilisent intensivement les regex pour le traitement de texte.
Bien que la syntaxe de base des regex soit très standardisée (POSIX, PCRE), il existe de légères variations ("flavors") entre les outils et les langages. Les fonctionnalités avancées comme les lookarounds peuvent ne pas être supportées partout.

Délimiteurs et Modificateurs (Flags)

Lorsque vous utilisez des regex dans certains contextes (notamment en programmation), vous devez souvent encadrer votre motif avec des délimiteurs et pouvez ajouter des modificateurs (flags) après le délimiteur de fin.

Délimiteurs

Ils indiquent où commence et où finit le motif regex. Le choix du délimiteur peut varier :

  • PHP (PCRE) : Le plus courant est le slash /. Ex: /motif/. Vous pouvez utiliser d'autres caractères comme # ou ~ si votre motif contient des slashes. Ex: #^https?://#.
  • JavaScript : Utilise nativement les slashes. Ex: /motif/. Ou via le constructeur new RegExp("motif", "flags").
  • Python : Pas de délimiteurs explicites requis. On utilise souvent les "raw strings" r"..." pour éviter les problèmes avec les backslashes \. Ex: r"\d+". Les flags sont passés comme arguments aux fonctions du module re.
  • Perl : Très flexible, mais / est courant. Ex: /motif/.

Modificateurs (Flags)

Ce sont les mêmes que ceux vus précédemment, mais appliqués différemment selon le contexte.

Modificateur Description Exemple PHP Exemple JS Exemple Python (arg)
g Global (trouver toutes les occurrences) (via preg_match_all) /motif/g (via re.findall)
i Insensible à la casse /motif/i /motif/i re.IGNORECASE
m Multi-lignes (^, $ par ligne) /motif/m /motif/m re.MULTILINE
s Single line / dotall (. matche \n) /motif/s /motif/s (ES2018+) re.DOTALL
u Support Unicode complet (PCRE) /motif/u /motif/u (ES2015+) (Python 3 par défaut)
x Ignore les espaces et permet les commentaires # dans le motif /motif /x (Non standard JS) re.VERBOSE

Exemple combiné en PHP : /^lign. (\d+)/im : Cherche au début de chaque ligne (m), sans tenir compte de la casse (i), le texte "lign", suivi d'un caractère quelconque, d'un espace, puis capture un ou plusieurs chiffres.

La manière d'appliquer les flags (après le délimiteur, comme argument de fonction, etc.) dépend fortement de l'outil ou du langage que vous utilisez. Consultez toujours sa documentation spécifique !

Conclusion

Les expressions régulières sont un outil puissant pour manipuler du texte et extraire des données. En les apprenant pas à pas, vous pourrez les utiliser efficacement dans divers outils et langages.

Bon apprentissage et pratiquez avec des outils comme regex101.