Choisir LESQUELS, pas matcher tout
À la leçon 1, tu as rencontré le point. Le point matche presque tout : une lettre, un chiffre, un espace, n'importe quel caractère. Pratique, mais brutal. Quand tu veux valider un code postal ou repérer une voyelle, « n'importe quel caractère » est beaucoup trop large.
Cette leçon répond à la question suivante : et si je veux choisir lesquels ? Pas « un caractère quelconque », mais « un caractère parmi cette liste précise ». C'est exactement le rôle des classes de caractères. Tu vas passer du fusil à pompe au tir de précision.
La classe [abc] : un caractère parmi une liste
Mets des caractères entre crochets, et tu obtiens une classe de caractères. Elle matche un seul caractère, à condition qu'il fasse partie de la liste. [abc] veut dire « un a, ou un b, ou un c ». Pas les trois à la suite : un seul, au choix.
L'exemple canonique des regex, c'est l'orthographe de « gris » en anglais. Les Britanniques écrivent grey, les Américains gray. Une seule lettre change. Avec une classe, tu couvres les deux d'un coup :
gr[ae]y
Lis le motif lettre par lettre : un g, un r, puis un caractère qui est soit a soit e, puis un y. Donc gray passe, grey passe, mais griy est rejeté : le i n'est ni a ni e.
Le vocabulaire : on appelle ça une classe de caractères. Les crochets [ ] définissent un ensemble, et la regex pioche un caractère dedans. Retiens bien « un parmi » : c'est la clé de toute la leçon.
À toi : couvre les deux orthographes
Écris un motif qui matche gray et grey, mais ni griy ni groy. Tape ton motif et regarde le surlignage se mettre à jour en direct.
Bloqué ? Voir une solution
Le motif est gr[ae]y. La classe [ae] accepte un a OU un e à cette position précise. griy et groy échouent parce que i et o ne sont pas dans la classe.
Les plages et la négation
Lister chaque caractère devient vite pénible. Pour « toutes les lettres minuscules », tu n'écris pas [abcdefghijklmnopqrstuvwxyz] : tu écris une plage avec un tiret.
[a-z]: une lettre minuscule, deaàz.[0-9]: un chiffre, de0à9.[a-zA-Z0-9]: on cumule les plages dans une seule classe. Ici : une lettre (minuscule ou majuscule) ou un chiffre.
Le tiret entre deux caractères veut dire « tout l'intervalle entre les deux ». L'ordre suit le code des caractères : a à z, 0 à 9. Simple et compact.
Et si tu veux l'inverse ? « N'importe quel caractère sauf ceux-là » ? Tu places un accent circonflexe ^ juste après le crochet ouvrant. C'est la négation :
[^aeiou]
Ça matche un caractère qui n'est aucune des voyelles listées. Une consonne, un chiffre, un espace, une ponctuation : tout sauf a, e, i, o, u.
Le ^ ne veut dire « sauf » qu'en PREMIÈRE position dans la classe. Dans [^abc], le ^ juste après le crochet inverse la classe. Mais dans [a^bc], le ^ est au milieu : il redevient un caractère ordinaire, et la classe matche simplement a, ^, b ou c. Attention aussi : en dehors d'une classe, le ^ a un tout autre sens, c'est une ancre de début de ligne. On le verra à la leçon 4. Pour l'instant, retiens juste : ^ en tête de classe = négation.
Tu écris le motif [^0-9] et tu le testes sur la chaîne "a", puis sur "5". Lequel des deux matche ?
Voir la réponse
C'est "a" qui matche, pas "5". [^0-9] veut dire « un caractère qui n'est PAS un chiffre ». Le ^ en tête inverse la plage 0-9. Donc a (qui n'est pas un chiffre) passe, et 5 (qui en est un) est rejeté. Si tu avais oublié le ^, [0-9] aurait fait exactement l'inverse.
À toi : une voyelle au milieu
Trouve un motif qui matche bag, bog et bug, mais pas bxg. Indice : il faut un b, puis une voyelle, puis un g.
Bloqué ? Voir une solution
Le motif est b[aeiou]g. La classe [aeiou] liste les cinq voyelles. bxg échoue car x n'en fait pas partie.
À toi : tout sauf un h
Cette fois, sers-toi de la négation. Écris un motif qui matche ccat et cxat, mais surtout PAS chat. Autrement dit : un c, puis un caractère qui n'est pas un h, puis at.
Bloqué ? Voir une solution
Le motif est c[^h]at. La classe [^h] accepte n'importe quel caractère sauf h. chat est donc rejeté, alors que ccat et cxat passent.
Les raccourcis : \d, \w, \s
Certaines classes reviennent tellement souvent que les regex leur donnent un raccourci. Au lieu d'écrire la classe en entier, tu écris une lettre précédée d'un antislash :
\d: un chiffre. C'est exactement[0-9](ledde digit).\w: un caractère « de mot », c'est-à-dire[a-zA-Z0-9_]: lettres, chiffres et le tiret bas. Lewde word.\s: un caractère d'espacement : espace, tabulation, retour à la ligne. Lesde space.
Et leurs versions majuscules sont l'inverse exact : \D = tout sauf un chiffre, \W = tout sauf un caractère de mot, \S = tout sauf un espace. La majuscule nie, comme un [^...] tout prêt.
Un fait que beaucoup de tutoriels ratent : en JavaScript, \d et \w sont ASCII uniquement. \w ne contient que [a-zA-Z0-9_] : un é, un ñ ou un ç ne sont PAS des \w ! Si tu valides des noms français avec \w, tu rejetteras « Cécile » ou « René ». Pour inclure les accents, il faut soit les lister à la main, soit utiliser des classes Unicode (au programme d'une autre leçon). Garde juste ce réflexe : \w n'est pas « toute lettre », c'est « lettre ASCII, chiffre ou underscore ».
Le piège qui trompe tout le monde : [] n'est pas ()
Voici la confusion numéro un des débutants en regex, celle qui mérite que tu t'arrêtes dix secondes. Les crochets et les parenthèses n'ont rien à voir.
[abc]matche UN caractère parmi : una, ou unb, ou unc.(abc)matche la SÉQUENCEabc: unasuivi d'unbsuivi d'unc, dans cet ordre. C'est un groupe, le sujet de la leçon 5.
Le piège exact : le motif [chat] ne matche PAS le mot « chat » ! Les crochets en font une classe de caractères : [chat] matche un seul caractère, à savoir c, h, a OU t. L'ordre est ignoré, les doublons aussi. Pour matcher le mot « chat » dans son entier, il faut écrire chat tout court (quatre littéraux à la suite), ou un groupe (chat) si tu veux le capturer. Règle à graver : crochets = un parmi, parenthèses = une séquence.
À toi : valider un code postal
Un code postal français, c'est cinq chiffres. Écris un motif qui matche 25000 et 75011, mais ni 7501A (une lettre traîne) ni ABCDE (que des lettres).
Petit indice : tu ne connais pas encore la répétition. Alors écris simplement \d cinq fois de suite. Oui, c'est un peu lourd. On verra mieux juste après.
Bloqué ? Voir une solution
Le motif est \d\d\d\d\d : cinq classes « chiffre » à la suite. 7501A n'a que quatre chiffres consécutifs, et ABCDE aucun. Écrire \d cinq fois pique un peu : la leçon 3 te montrera \d{5}, bien plus net.
Choosing WHICH ones, not matching everything
In lesson 1 you met the dot. The dot matches almost anything: a letter, a digit, a space, any character at all. Handy, but blunt. When you want to validate a postcode or spot a vowel, "any character" is far too broad.
This lesson answers the next question: what if I want to choose which ones? Not "any character", but "a character from this precise list". That's exactly what character classes are for. You're trading the shotgun for a precision rifle.
The [abc] class: one character from a list
Put characters between brackets and you get a character class. It matches a single character, as long as it belongs to the list. [abc] means "an a, or a b, or a c". Not all three in a row: just one, your pick.
The canonical regex example is the spelling of "grey". The British write grey, the Americans gray. A single letter changes. With a class you cover both at once:
gr[ae]y
Read the pattern letter by letter: a g, an r, then a character that's either a or e, then a y. So gray passes, grey passes, but griy is rejected: i is neither a nor e.
The vocabulary: this is called a character class. The brackets [ ] define a set, and the regex picks one character from it. Remember "one from": it's the key to the whole lesson.
Your turn: cover both spellings
Write a pattern that matches gray and grey, but neither griy nor groy. Type your pattern and watch the highlighting update live.
Stuck? See a solution
The pattern is gr[ae]y. The class [ae] accepts an a OR an e at that exact spot. griy and groy fail because i and o aren't in the class.
Ranges and negation
Listing every character quickly gets tedious. For "all lowercase letters" you don't write [abcdefghijklmnopqrstuvwxyz]: you write a range with a hyphen.
[a-z]: a lowercase letter, fromatoz.[0-9]: a digit, from0to9.[a-zA-Z0-9]: you stack ranges inside a single class. Here: a letter (lower or upper) or a digit.
The hyphen between two characters means "the whole interval between them". The order follows the character code: a to z, 0 to 9. Simple and compact.
And if you want the opposite? "Any character except those"? You place a caret ^ right after the opening bracket. That's negation:
[^aeiou]
This matches a character that is none of the listed vowels. A consonant, a digit, a space, a punctuation mark: anything except a, e, i, o, u.
The ^ only means "except" in the FIRST position inside the class. In [^abc], the ^ right after the bracket negates the class. But in [a^bc], the ^ is in the middle: it becomes an ordinary character again, and the class simply matches a, ^, b or c. Beware too: outside a class, ^ has a completely different meaning, it's a start-of-line anchor. We'll see that in lesson 4. For now, just remember: ^ at the start of a class = negation.
You write the pattern [^0-9] and test it on the string "a", then on "5". Which of the two matches?
Show the answer
It's "a" that matches, not "5". [^0-9] means "a character that is NOT a digit". The leading ^ inverts the 0-9 range. So a (not a digit) passes, and 5 (a digit) is rejected. Had you forgotten the ^, [0-9] would do exactly the opposite.
Your turn: a vowel in the middle
Find a pattern that matches bag, bog and bug, but not bxg. Hint: you need a b, then a vowel, then a g.
Stuck? See a solution
The pattern is b[aeiou]g. The class [aeiou] lists the five vowels. bxg fails because x isn't one of them.
Your turn: anything but an h
This time, use negation. Write a pattern that matches ccat and cxat, but above all NOT chat. In other words: a c, then a character that isn't an h, then at.
Stuck? See a solution
The pattern is c[^h]at. The class [^h] accepts any character except h. chat is therefore rejected, while ccat and cxat pass.
The shortcuts: \d, \w, \s
Some classes come up so often that regex gives them a shortcut. Instead of writing the whole class, you write a letter preceded by a backslash:
\d: a digit. It's exactly[0-9](thedof digit).\w: a "word" character, that is[a-zA-Z0-9_]: letters, digits and the underscore. Thewof word.\s: a whitespace character: space, tab, newline. Thesof space.
And their uppercase versions are the exact opposite: \D = anything but a digit, \W = anything but a word character, \S = anything but whitespace. The uppercase negates, like a ready-made [^...].
A fact many tutorials get wrong: in JavaScript, \d and \w are ASCII only. \w contains only [a-zA-Z0-9_]: an é, an ñ or a ç are NOT \w! If you validate French names with \w, you'll reject "Cécile" or "René". To include accents you must either list them by hand or use Unicode classes (a topic for another lesson). Just keep this reflex: \w isn't "any letter", it's "ASCII letter, digit or underscore".
The trap that fools everyone: [] is not ()
Here's the number one confusion for regex beginners, the one worth pausing ten seconds for. Brackets and parentheses have nothing to do with each other.
[abc]matches ONE character from: ana, or ab, or ac.(abc)matches the SEQUENCEabc: anafollowed by abfollowed by ac, in that order. It's a group, the subject of lesson 5.
The exact trap: the pattern [chat] does NOT match the word "chat"! The brackets make it a character class: [chat] matches a single character, namely c, h, a OR t. Order is ignored, so are duplicates. To match the whole word "chat", you write chat on its own (four literals in a row), or a group (chat) if you want to capture it. A rule to carve in: brackets = one from, parentheses = a sequence.
Your turn: validate a postcode
A French postcode is five digits. Write a pattern that matches 25000 and 75011, but neither 7501A (a letter lingers) nor ABCDE (all letters).
Small hint: you don't know repetition yet. So just write \d five times in a row. Yes, it's a bit clunky. We'll do better right after.
Stuck? See a solution
The pattern is \d\d\d\d\d: five "digit" classes in a row. 7501A has only four consecutive digits, and ABCDE none. Writing \d five times stings a little: lesson 3 will show you \d{5}, far neater.
🎯 Pratique
S'entraîner (clique pour ouvrir) :
💬 Ré-explique sans regarder
Explique à un collègue la différence entre [chat] et (chat), et combien de caractères chacun matche.
[chat] est une classe, elle matche un seul caractère, soit c, h, a ou t (l'ordre et les doublons sont ignorés). (chat) est un groupe, il matche la séquence de quatre caractères c, h, a, t dans cet ordre. Règle : crochets = un parmi, parenthèses = une séquence.🧠 Rappel libre
Sans remonter : à quelle classe correspond \d, et où faut-il placer le ^ pour qu'il signifie « sauf » ?
\d correspond exactement à [0-9], un chiffre. Le ^ ne signifie « sauf » qu'en première position dans la classe : [^...]. Ailleurs dans la classe, il redevient un caractère ordinaire. Et hors classe, ^ est une ancre de début de ligne (leçon 4).⚖️ Juge le code de l'IA
Tu demandes à l'IA une classe qui matche « toutes les lettres, majuscules et minuscules ». Elle répond : « Facile, utilise [A-z], ça couvre de A à z d'un seul coup. » Tu acceptes, ou tu rejettes ?
[A-z] ne couvre PAS « toutes les lettres ». Entre Z et a dans la table des caractères, il y a six symboles : [, \, ], ^, _ et `. [A-z] les laisse donc passer, ce qui crée des trous de validation discrets. La bonne classe est [A-Za-z] : deux plages séparées, sans rien entre les deux. Méfie-toi des plages « malines » qui sautent par-dessus des symboles.gr[ae]y ?é est-il un \w ?/[chat]/ ?Écrire \d cinq fois, ça pique. Leçon 3 : les quantificateurs, ces symboles qui répètent un motif (\d{5} au lieu de cinq \d). Et LE piège le plus célèbre des regex : le .* gourmand qui avale tout, montré en direct avant que tu apprennes à le dompter.
Leçon 3 : Quantificateurs et greedy →