Les classes de caractères en regex : \d, \w, \s, [a-z] et leurs pièges
Les classes de caractères sont la partie la plus utilisée des regex, et celle où l'on se trompe le plus facilement sans s'en rendre compte. Ce que [abc], [a-z], [^…], \d, \w et \s trouvent vraiment, et les pièges qui se cachent derrière : [A-z], le tiret égaré, le point entre crochets et les chiffres qui ne sont pas de 0 à 9.

· 8 min de lecture
/^[A-Z][a-z]+$/
à attraper
- Paris
- Lima
- Oslo
- Rome
à épargner
- paris
- PARIS
- New York
- R2D2
Une classe de caractères correspond à un caractère d'un ensemble. [aeiou] correspond à une voyelle. [0-9] correspond à un chiffre. \s correspond à un espace, une tabulation ou un saut de ligne.
On les retrouve dans presque tous les motifs, et la plupart de leurs pièges sont silencieux : le motif marche sur les entrées que vous avez testées, puis laisse passer quelque chose de bizarre plus tard. Cet article explique ce que chaque classe trouve vraiment, puis passe aux pièges. Chaque exemple est interactif : modifiez les motifs et regardez les lignes changer.
01Un ensemble entre crochets
Les crochets listent les caractères autorisés à une position :
greay échoue parce que la classe occupe exactement une case. Pour autoriser plus d'un caractère, ajoutez un quantificateur après : [ae]+.
02Les plages
Un tiret entre deux caractères signifie « tout ce qui se trouve entre les deux », selon le code des caractères :
/^[A-Z][a-z]+$/Doit correspondre2/2
- Paris
- Lima
Ne doit pas3/3
- paris
- PARIS
- New York
Vous pouvez mettre plusieurs plages et caractères isolés dans une même classe : [A-Za-z0-9_] regroupe lettres, chiffres et tiret bas.
03Les classes négatives
Un ^ juste après le crochet ouvrant inverse l'ensemble : « n'importe quel caractère sauf ceux-ci ».
/^[^aeiou]+$/Doit correspondre3/3
- rhythm
- myths
- 2024
Ne doit pas2/2
- cat
- queue
Attention : « n'importe quel caractère sauf » veut vraiment dire n'importe lequel : espaces, chiffres, ponctuation et sauts de ligne comptent tous. 2024 correspond, car les chiffres ne sont pas des voyelles.
En dehors des crochets, ^ est une ancre. À l'intérieur, tout au début, c'est une négation. Partout ailleurs à l'intérieur, c'est juste un accent circonflexe.
04Les raccourcis
Certaines classes sont si courantes qu'elles ont un nom court :
| Raccourci | Signification (en JavaScript) | Contraire |
|---|---|---|
\d |
un chiffre, [0-9] |
\D |
\w |
un caractère de mot, [A-Za-z0-9_] |
\W |
\s |
un espacement : espace, tabulation, saut de ligne et compagnie | \S |
. |
n'importe quel caractère sauf un saut de ligne |
Deux d'entre eux surprennent. \w inclut les chiffres et le tiret bas, ce n'est donc pas « une lettre » :
/^\w+$/Doit correspondre3/3
- hello
- snake_case
- R2D2
Ne doit pas2/2
- kebab-case
- two words
Et \s ne se limite pas à l'espace : il correspond aussi aux tabulations et aux sauts de ligne. Si vous voulez exactement un espace, écrivez un espace.
05Piège 1 : [A-z] ne veut pas dire « toutes les lettres »
Les plages suivent les codes des caractères. Entre Z (90) et a (97) se trouvent six autres caractères : [ \ ] ^ _ et l'accent grave. Donc [A-z] les laisse passer :
/^[A-z]+$/Doit correspondre3/3
- Hello
- snake_case
- up^down
Ne doit pas1/1
- 2024
Écrivez les deux plages séparément : [A-Za-z].
06Piège 2 : le tiret au milieu
Un tiret entre deux caractères crée une plage, même quand vous vouliez un tiret littéral :
Cette virgule, c'est le bug : + a le code 43, . le 46, et la virgule (44) se trouve entre les deux. Placez le tiret en premier ou en dernier dans la classe, ou échappez-le, et ce redevient un simple tiret :
07Piège 3 : le point et les autres caractères spéciaux
La plupart des caractères spéciaux perdent leurs pouvoirs entre crochets. [.] est un point littéral, [*+?] est l'un de ces trois symboles, et [$] est un signe dollar. [.] est donc une autre façon d'écrire \. :
Seuls quatre caractères restent spéciaux dans une classe : ], \, ^ au début, et - entre deux caractères.
08Piège 4 : des chiffres qui ne sont pas de 0 à 9
En JavaScript, \d vaut exactement [0-9]. En Python 3, sur un motif str normal, \d correspond à n'importe quel chiffre Unicode : les chiffres indo-arabes comme ٣, devanagari comme ३ ou pleine chasse comme 3. Il en va de même pour \w, qui accepte les lettres de n'importe quelle écriture.
import re
re.fullmatch(r"\d+", "٣٤٥") # matches in Python
re.fullmatch(r"\d+", "٣٤٥", re.ASCII) # None
Si un nombre est sur le point de passer dans int() ou dans une colonne de base de données, ça compte. Utilisez [0-9], ou le marqueur re.ASCII, quand vous voulez des chiffres ASCII.
09À vous de jouer
Saurez-vous attraper les lignes composées uniquement de chiffres hexadécimaux ?
Attrapez les chaînes composées uniquement de chiffres hexadécimaux, en majuscules ou en minuscules.
Cibles · 0/6 attrapées
- ffcible
- 00cible
- 1a2Bcible
- DEADbeefcible
- c0ffeecible
- 7cible
Innocents · erreurs : 0
- fginnocent
- 0x1finnocent
- 12 34innocent
- beef!innocent
- gginnocent
- zinnocent
Tapez une regex — le plateau se met à jour en direct.
10Récapitulatif
[abc]correspond à un caractère de l'ensemble. Ajoutez un quantificateur pour en avoir plus.[^abc]correspond à tout caractère absent de l'ensemble, espaces et sauts de ligne compris.- Écrivez
[A-Za-z], jamais[A-z]. - Placez un tiret littéral en premier ou en dernier :
[\w.-]. - Entre crochets,
.*+?$sont littéraux. \winclut les chiffres et_.\sinclut les tabulations et les sauts de ligne.- En Python,
\det\wgèrent l'Unicode. Utilisez[0-9]oure.ASCIIpour vous limiter à l'ASCII.
11Continuez à vous entraîner
- Châteaux de caractères et Patrouille des raccourcis sont des packs d'entraînement qui travaillent exactement ce sujet.
- Le guide consacre une section complète aux classes et aux raccourcis.