Regex - 04 - Classes de caractères : définir tes propres ensembles

Les classes de caractères regex [abc], les ranges, les negations et les raccourcis comme backslash-d, backslash-w, backslash-s.

04 - Classes de caractères : définir tes propres ensembles

Ce que tu vas apprendre

  • Les classes [abc] pour matcher un caractère parmi un ensemble
  • Les ranges [a-z], [0-9] pour définir des plages
  • La negation [^abc] pour exclure des caractères
  • Les raccourcis \d, \w, \s et leurs negations
  • Les pièges du tiret dans une classe

Prerequisites

Avoir compris les ancres et les quantificateurs.


Le problème : matcher un caractère parmi plusieurs

Tu veux trouver les mots "chat", "chot", "chut" mais pas "cht" ni "chait". Le point . est trop permissif (il accepte tout), et lister les alternatives une par une serait penible.

Les classes de caractères resolvent ce problème. Elles definissent un ensemble de caractères acceptables pour une seule position.

La classe basique `[abc]`

Les crochets [] definissent une classe. [aou] matche UN caractère qui est soit a, soit o, soit u.

ch[aou]t

Teste avec :

chat
chot
chut
chit
cht
chaat

Matche : "chat", "chot", "chut". Ne matche pas "chit" (i n'est pas dans la classe), "cht" (il faut un caractère), "chaat" (un seul caractère attendu).

La classe ne consomme qu'un seul caractère. C'est un sélecteur, pas un quantificateur.

Les ranges `[a-z]`

Lister tous les caractères un par un serait fastidieux. Les ranges permettent de définir des plages :

  • [a-z] : toutes les lettres minuscules de a a z
  • [A-Z] : toutes les lettres majuscules
  • [0-9] : tous les chiffres
  • [a-f] : les lettres de a a f (utile pour l'hexadecimal)

Tu peux combiner plusieurs ranges dans une meme classe :

[a-zA-Z]

Matche n'importe quelle lettre, minuscule ou majuscule.

[a-zA-Z0-9]

Matche une lettre ou un chiffre.

Un exemple pratique : matcher un identifiant hexadecimal de 6 caractères (comme une couleur CSS) :

#[0-9a-fA-F]{6}

Teste avec :

#FF5733
#00aaff
#ZZZZZZ
#123

Seuls "#FF5733" et "#00aaff" matchent. "#ZZZZZZ" echoue (Z n'est pas hexadecimal) et "#123" est trop court.

La negation `[^abc]`

Le ^ a l'intérieur d'une classe de caractères signifie "tout sauf". Attention, c'est un sens différent du ^ comme ancre de début de chaîne.

[^0-9]

Matche tout caractère qui n'est PAS un chiffre.

[^aeiou]

Matche tout caractère qui n'est PAS une voyelle minuscule.

Rappelle-toi l'article sur les quantificateurs ou j'ai mentionne [^"]* comme alternative au lazy. Maintenant tu comprends pourquoi : [^"]* signifie "zero ou plusieurs caractères qui ne sont pas un guillemet".

"[^"]*"

C'est souvent la meilleure facon d'extraire du contenu entre delimiteurs. Plus explicite et plus performant que ".*?".

Les raccourcis : `\d`, `\w`, `\s`

Les regex offrent des raccourcis pour les classes les plus courantes :

Raccourci Équivalent Signification
\d [0-9] Un chiffre
\w [a-zA-Z0-9_] Un caractère de "mot"
\s [ \t\n\r\f] Un espace blanc

Le \w inclut l'underscore, ce qui le rend parfait pour les noms de variables dans la plupart des langages.

Ces raccourcis se combinent avec les quantificateurs :

\d+

Un ou plusieurs chiffres. Tu l'as deja vu, c'est une des regex les plus utiles.

\w+

Un ou plusieurs caractères de mot. Parfait pour extraire des mots ou des identifiants.

\s+

Un ou plusieurs espaces. Utile pour splitter du texte ou normaliser des espaces multiples.

Les negations : `\D`, `\W`, `\S`

Chaque raccourci a sa version negee en majuscule :

Raccourci Équivalent Signification
\D [^0-9] Tout sauf un chiffre
\W [^a-zA-Z0-9_] Tout sauf un caractère de mot
\S [^\s] Tout sauf un espace blanc

\S+ est pratique pour matcher "tout ce qui n'est pas un espace", c'est-a-dire un bloc de texte continu.

Le piège du tiret `-`

Dans une classe de caractères, le tiret a une signification speciale : il definit une range. Mais que faire si tu veux matcher un tiret litteral ?

Deux solutions :

Le mettre au début ou a la fin de la classe :

[-a-z]

Matche un tiret ou une lettre minuscule.

[a-z-]

Meme chose, tiret a la fin.

L'echapper :

[a\-z]

Mais c'est moins lisible. La convention, c'est de le mettre au début ou a la fin.

Un cas concret : matcher un slug d'URL (lettres minuscules, chiffres et tirets) :

^[a-z0-9-]+$

Le tiret est a la fin de la classe, donc il est litteral. Sur paltemps.fr, c'est exactement ce genre de regex qu'on utilise pour valider les slugs de nos articles.

Combiner classes et quantificateurs

La vraie puissance vient de la combinaison :

Un numero de telephone français avec separateurs optionnels :

^0[1-9][\s.-]?\d{2}[\s.-]?\d{2}[\s.-]?\d{2}[\s.-]?\d{2}$

[\s.-]? signifie "optionnellement un espace, un point ou un tiret". Ca matche :

  • 0612345678
  • 06 12 34 56 78
  • 06.12.34.56.78
  • 06-12-34-56-78

Un mot en français avec accents :

[a-zA-ZeaeuuoicE]+

Bon, la ca devient penible. Pour les caractères accentues, les regex classiques sont limitees. Les classes Unicode (\p{L} pour "n'importe quelle lettre") sont plus adaptees mais pas supportees partout.

Exemple : valider un mot de passe

Une regex classique d'entretien technique (que je n'aime pas mais qu'on voit partout) :

"Le mot de passe doit contenir au moins 8 caractères, une majuscule, une minuscule et un chiffre."

On pourrait etre tente d'écrire une seule regex, mais c'est plus lisible avec plusieurs tests :

.{8,}       // au moins 8 caracteres
[A-Z]       // contient une majuscule
[a-z]       // contient une minuscule
[0-9]       // contient un chiffre

Quatre regex simples plutot qu'une regex illisible. C'est souvent la bonne approche en production.

Résumé

  • [abc] matche un caractère parmi l'ensemble défini
  • [a-z] definit une plage (range) de caractères
  • [^abc] matche tout caractère SAUF ceux listes
  • \d, \w, \s sont des raccourcis pour les classes courantes
  • \D, \W, \S sont leurs negations
  • Le tiret - doit etre au début ou a la fin de la classe pour etre litteral
  • Combiner classes et quantificateurs donne des patterns puissants et lisibles

Article précédent 03 - Ancres
Article suivant 05 - Groupes

Sources

Réservez un audit gratuit de 30 minutes. Je vous montre concrètement ce qu'on peut automatiser.