Mini-test 10

REGEX

Expressions regulieres : decrire un motif et l'utiliser avec grep et sed

12 questions ciblees

classes [ ] + ? * { } grep -E sed s///

Cliquez Voir la solution sur chaque slide

← → naviguer · I indice · S solution · R recommencer

Question 1 / 12 choisir un caractere (drag-and-drop)

Le bon symbole pour le bon caractere

Cinq facons de designer un caractere ou une chaine en regex. Glissez chaque motif vers la description qui lui correspond.
[a-z]
[^0-9]
.
allo
[0-9]

5 motifs et leur signification :

N'importe quel caractere
(joker)
Un chiffre
(0 a 9)
Tout SAUF un chiffre
(negation)
Une lettre minuscule
(a a z)
Le mot "allo"
(chaine litterale)
Le point . est le joker universel. Les crochets [ ] definissent une classe (un caractere parmi). Le tiret entre 2 caracteres dans une classe = intervalle. ^ en debut de classe = negation. Sans crochets ni meta-caracteres = chaine litterale.
MotifMatchExemples
.N'importe quel caractere uniquea, Z, 5, !, espace...
[0-9]Un chiffre0, 1, 2, ..., 9
[^0-9]Tout SAUF un chiffrea, Z, !, espace... (mais pas 0-9)
[a-z]Une lettre minusculea, b, c, ..., z
alloLa chaine litterale "allo"allo (et juste allo, dans cet ordre)

Note importante : sans meta-caracteres (ni ., ni [], ni +...), une regex est juste une chaine litterale. allo matche le mot allo. 418 matche les 3 chiffres 4, 1, 8 dans cet ordre.

Autres classes utiles :

[A-Z]       une lettre majuscule
[A-Za-z]    une lettre (peu importe la casse)
[a-zA-Z0-9] alphanumerique
[0-9a-fA-F] un chiffre hexa

Question 2 / 12 multiplicateurs (drag-and-drop)

Repeter un caractere : associer chaque symbole a son sens

Glissez chaque multiplicateur vers la description qui lui correspond. Cliquez sur une etiquette deja deposee pour la retirer.
{3}
*
?
{3,5}
+

5 multiplicateurs et leur signification :

0 ou 1 fois
(facultatif)
1 ou plusieurs
(au moins une)
0 ou plusieurs
(rien ou plein)
Exactement 3
(precis)
Entre 3 et 5
(intervalle)
Symboles courts pour les cas frequents : ? facultatif, + au moins une, * zero ou plus. Pour des comptes precis : {N} exact, {N,M} intervalle.
SymboleSignification
?0 ou 1 fois (facultatif)
+1 ou plusieurs (au moins une)
*0 ou plusieurs (eventuellement aucune)
{3}Exactement 3 fois
{3,5}Entre 3 et 5 fois

Equivalences :

{0,1}   equivalent a ?
{1,}    equivalent a +
{0,}    equivalent a *
{,5}    au maximum 5 fois
{3,}    au moins 3 fois

Exemples concrets :

colou?r       matche "color" ET "colour"
hel+o         matche "helo", "hello", "helllo"...
[0-9]{4}      exactement 4 chiffres (annee)
[a-z]{3,8}    mot de 3 a 8 lettres minuscules

Question 3 / 12 ancres + echappement (drag-and-drop)

Associer chaque symbole a son role

Le meme symbole peut avoir des roles differents selon ou il apparait dans la regex. Glissez chaque exemple vers la description qui lui correspond.
^abc
[^abc]
abc$
\$
[abc-]

5 contextes possibles pour ^, $ et - :

Debut de ligne
(ancre)
Fin de ligne
(ancre)
Tout SAUF a, b, c
(negation dans classe)
Le caractere $
(litteral, echappe)
Le caractere -
(litteral en fin de classe)
^ et $ ont 2 sens : ancre quand seuls, negation quand au DEBUT d'une classe [ ]. Pour rendre un meta-caractere litteral : soit l'echapper avec \, soit le mettre a un endroit ou il n'a pas de sens special (ex. - en fin de classe).
FormeRole
^abcAncre debut de ligne : abc doit etre au debut
abc$Ancre fin de ligne : abc doit etre a la fin
[^abc]Negation dans classe : un caractere SAUF a, b, c
\$Echappement : le caractere $ litteral
[abc-]Tiret en fin de classe : litteral (pas un intervalle)

Memo important : 2 sens pour ^

Memo important : le tiret - dans une classe

Question 4 / 12 intervalle vs liste de caracteres

Distinguer un intervalle d'une liste

Dans une classe de caracteres [ ], le tiret change tout. Comparons deux motifs qui se ressemblent visuellement.
[0-9]
Le nombre
entre 0 et 9
Un seul chiffre
entre 0 et 9
La chaine
"0-9"
3 caracteres :
0, -, 9
[009]
Le nombre
009
Les 3 chiffres
dans cet ordre
Un seul chiffre
0 ou 9
N'importe quel
chiffre
c) Pour matcher le nombre 009 (trois chiffres exactement dans cet ordre, sans crochets), donnez la regex :
Les [ ] definissent une liste de caracteres possibles, un seul est choisi. Le tiret entre 2 caracteres = intervalle. Sans tiret = liste litterale. Pour matcher une chaine de plusieurs caracteres dans l'ordre, on les met cote a cote SANS crochets.

[0-9] = un seul caractere parmi l'intervalle 0 a 9 (donc 0, 1, 2, ..., 9). Le tiret signifie "intervalle".

[009] = un seul caractere parmi la liste {0, 0, 9}. Le 0 est en double mais c'est comme si on avait [09]. Donc : 0 ou 9.

009 (sans crochets) = la chaine litterale 009 (trois caracteres dans cet ordre).

MotifMatch ?Exemples qui matchent
[0-9]1 chiffre0, 1, 2, 3, 4, 5, 6, 7, 8, 9
[009]1 chiffre0 ou 9 (le 0 en double sert a rien)
0093 caracteres009 (et seulement 009)
[0-9]{3}3 chiffres000, 123, 456, 999...

Piege classique : [A-z] n'est PAS [A-Za-z] ! Entre Z et a dans la table ASCII, il y a des caracteres comme [ \ ] ^ _ `. Toujours preferer [A-Za-z].

Question 5 / 12 concatenation et alternation (QCM)

Coller ou choisir : "chat", "ouille" et "chatouille"

Trois mots qui se ressemblent : chat, ouille et leur fusion chatouille. Selon comment on les ecrit dans une regex, ils peuvent etre concatenes (colles) ou des alternatives.
chatouille
La chaine litterale
"chatouille"
chat OU ouille
(au choix)
Un seul caractere
parmi c h a t o u i l e
Syntaxe
invalide
chat|ouille
La chaine litterale
"chat|ouille"
chat OU ouille
(au choix)
Un seul caractere
parmi c h a t | o u i l e
chatouille
(concatene)
[chatouille]
La chaine
"chatouille"
chat OU ouille
UN seul caractere
parmi c h a t o u i l e
Syntaxe
invalide
(chat|ouille)+
Une seule occurrence
de chat ou ouille
La chaine "chatouille"
exactement
Une ou plusieurs
occurrences de
chat ou ouille
Syntaxe
invalide
Sans [ ] ni |, on a une chaine litterale. Le | entre 2 mots cree des alternatives (mots entiers). Les [ ] ne contiennent que des caracteres (un seul est choisi). (...)+ repete tout le groupe.
RegexMatchExemples qui matchent
chatouilleChaine litteralechatouille (et juste chatouille)
chat|ouilleAlternation : un mot OU l'autrechat ou ouille (pas les deux)
[chatouille]Classe : UN SEUL caracterec, h, a, t, o, u, i, l, e (juste 1 lettre)
(chat|ouille)+Groupe + repetitionchat, ouille, chatchat, chatouille, ouillechat, chatouilleouillechat...

Memo crucial :

Question 6 / 12 indicatifs au choix (drag-and-drop)

5 ecritures pour les codes regionaux 418, 514, 819

Vous voulez reconnaitre un indicatif parmi 418, 514 ou 819. Voici 5 ecritures qui se ressemblent visuellement : associez chacune a ce qu'elle match reellement.
[418514819]
(418|514|819)
418|514|819
[418|514|819]
418

5 ecritures, 5 comportements differents :

418 OU 514 OU 819
(dans un groupe)
418 OU 514 OU 819
(sans groupe)
UN seul chiffre
parmi 1, 4, 5, 8, 9
UN seul caractere
parmi 1, 4, 5, 8, 9, |
La chaine exacte
418 (seulement)
Crochets [ ] = ensemble de caracteres, un seul est choisi. Pipe | = alternative entre des chaines, mais SEULEMENT en dehors des crochets. Dans une classe, le | est litteral. Le ( ) regroupe l'alternation.
EcritureMatch reellement
(418|514|819)418 OU 514 OU 819 (alternation groupee, capturable)
418|514|819418 OU 514 OU 819 (alternation sans groupe)
[418514819]UN seul chiffre parmi {1, 4, 5, 8, 9}
[418|514|819]UN seul caractere parmi {1, 4, 5, 8, 9, |}
418La chaine exacte 418 (3 chiffres dans cet ordre)

En pratique on prefere :

# Pour chainer avec le reste du numero
(418|514|819)-[0-9]{3}-[0-9]{4}

Question 7 / 12 cas pratique : telephone (1/2)

Construire pas a pas : numero local et indicatif fixe

On veut reconnaitre des numeros au format 555-1234 puis 418-555-1234. Construisons par etapes, du plus simple au plus complet. (Un indicatif au choix viendra a la page suivante.)
a) Format sans indicatif (3 chiffres, tiret, 4 chiffres) :
b) Avec un indicatif obligatoire (3 chiffres + tiret + numero local) :
c) Avec l'indicatif fixe a 418 (obligatoire, litteral) :
d) Avec l'indicatif 418 facultatif (peut etre la ou pas) :
[0-9]{N} = exactement N chiffres. Equivalent : repeter [0-9][0-9][0-9]. Pour rendre un fragment facultatif : l'entourer de parentheses et ajouter ? : (fragment)?. Le tiret hors classe est un caractere litteral.
# a) Sans indicatif (3 chiffres - 4 chiffres)
[0-9]{3}-[0-9]{4}
# Equivalent avec repetition manuelle
[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]

# b) Avec indicatif obligatoire (n'importe quel)
[0-9]{3}-[0-9]{3}-[0-9]{4}

# c) Indicatif fixe 418 (litteral)
418-[0-9]{3}-[0-9]{4}

# d) Indicatif 418 facultatif (groupe + ?)
(418-)?[0-9]{3}-[0-9]{4}

Notes :

La page suivante (Q8) generalise au cas ou l'indicatif peut etre l'un de plusieurs (418, 514, 819) avec ou sans parentheses.

Question 8 / 12 cas pratique : telephone (2/2)

Indicatif au choix et parentheses optionnelles

Maintenant l'indicatif n'est plus 418 seulement, c'est un choix parmi 418, 514, 819. Et certains formats americains entourent l'indicatif de parentheses : (418)-555-1234 ou 418-555-1234.
a) Indicatif au choix obligatoire parmi 418, 514 ou 819 :
b) Idem, mais l'indicatif est facultatif :
c) L'indicatif peut etre entoure de parentheses ou non : (418)-555-1234 OU 418-555-1234. Methode 1 : rendre chaque parenthese ( et ) facultative independamment :
Indicatif au choix : (418|514|819) dans un groupe. Pour rendre tout l'indicatif facultatif : entourer d'un groupe supplementaire avec ? : ((418|514|819)-)?. Pour les parentheses litterales ( et ) : les echapper avec \, et chacune devient facultative avec ? : \(? et \)?.
# a) Au choix obligatoire
(418|514|819)-[0-9]{3}-[0-9]{4}

# b) Au choix facultatif
((418|514|819)-)?[0-9]{3}-[0-9]{4}

# c) Methode 1 : chaque parenthese facultative independamment
\(?(418|514|819)\)?-[0-9]{3}-[0-9]{4}

Caracteristique de la methode 1 : les deux parentheses sont facultatives independamment l'une de l'autre. C'est plus court a ecrire, mais ca accepte aussi des cas asymetriques comme (418-555-1234 (parenthese ouvrante seule) ou 418)-555-1234 (fermante seule). Si on veut empecher l'asymetrie, il faut une alternative explicite : c'est l'objet de la question suivante (Q9).

Pour pratiquer les regex sur des exemples reels : regex101.com.

Question 9 / 12 parentheses : alternative explicite

Les parentheses ensemble ou pas du tout

Dans la question precedente, les parentheses etaient facultatives independamment : on acceptait aussi des cas asymetriques comme (418-555-1234 (ouvrante seule). Pour forcer la symetrie (les 2 parentheses ensemble ou aucune), on utilise une alternative explicite.

Donnez la regex qui matche (418)-555-1234 ou 418-555-1234 mais refuse (418-555-1234 et 418)-555-1234 :

Format : (motif_avec_parens|motif_sans_parens). Chacun des 2 motifs decrit l'indicatif complet (avec ses 2 parentheses, ou aucune). On echappe ( et ) pour le litteral : \( et \).
# Methode 2 : alternative explicite des deux formes complete
(\((418|514|819)\)|(418|514|819))-[0-9]{3}-[0-9]{4}

Decryptage :

Comparaison avec methode 1 (Q8c) :

EntreeMethode 1
(parens facultatives)
Methode 2
(alternative explicite)
(418)-555-1234OKOK
418-555-1234OKOK
(418-555-1234accepte (asymetrique)refuse
418)-555-1234accepte (asymetrique)refuse

Version "parfaite" avec ancres :

^(\((418|514|819)\)|(418|514|819))-[0-9]{3}-[0-9]{4}$

La methode 2 est plus stricte et plus correcte en production. La methode 1 est plus courte mais accepte des bizarreries que la methode 2 refuse.

Question 10 / 12 grep -E

Utiliser une regex avec grep

Le fichier /var/log/auth.log contient des lignes de connexion. On cherche.
a) Lignes qui contiennent "Failed password" :
b) Lignes qui contiennent "Failed" OU "Invalid" (REGEX alternation) :
c) Afficher seulement les correspondances (pas toute la ligne) :
grep de base utilise BRE (basique). -E active ERE (etendue) avec |, +, ? sans echappement. -o = output only matching part.
GREP(1) - extrait du manuel
NAME
       grep, egrep - print lines matching a pattern

SYNOPSIS
       grep [OPTION...] PATTERN [FILE...]

DESCRIPTION
       grep searches for PATTERN in each FILE.

OPTIONS

   Pattern Selection and Interpretation:
       -E, --extended-regexp
              Interpret PATTERN as an extended regular expression
              (ERE) - permits |, +, ?, (  ), {N,M} without backslash.

       -F, --fixed-strings
              Interpret PATTERN as fixed strings, not as a regex.

       -i, --ignore-case
              Ignore case distinctions in pattern and input files.

   General Output Control:
       -c, --count
              Suppress normal output; print a count of matching lines.

       -l, --files-with-matches
              Suppress normal output; print only the name of each
              input file from which output would normally be printed.

       -o, --only-matching
              Print only the matched (non-empty) parts of a matching
              line, with each such part on a separate output line.

       -v, --invert-match
              Invert the sense of matching, to select non-matching lines.

       -n, --line-number
              Prefix each line of output with the 1-based line number.

   Context Line Control:
       -r, --recursive
              Read all files under each directory, recursively.
# a) Recherche simple (motif fixe)
grep "Failed password" /var/log/auth.log

# b) Alternation : -E pour ERE, le | sans backslash
grep -E "Failed|Invalid" /var/log/auth.log

# c) Afficher seulement les matches (utile avec une regex precise)
grep -oE "Failed [a-z]+" /var/log/auth.log

Options frequentes de grep :

BRE vs ERE : En BRE (sans -E), + et ? doivent etre echappes \+ \?. Avec -E, ils gardent leur sens regex direct.

Question 11 / 12 sed s/.../.../

Remplacer avec sed

Vous avez un fichier de config avec d'anciennes lignes a remplacer.
a) Remplacer toutes les occurrences de "ERROR" par "WARN" dans app.log (afficher le resultat, sans modifier le fichier) :
b) Comme ci-dessus, mais modifier le fichier directement :
c) Supprimer toutes les lignes qui commencent par # (commentaires) dans config.conf :
Format de substitution : sed 's/MOTIF/REMPLACEMENT/FLAGS' fichier. Flag g = global (toutes les occurrences sur la ligne). -i = in-place. Pour supprimer : /motif/d.
SED(1) - extrait du manuel
NAME
       sed - stream editor for filtering and transforming text

SYNOPSIS
       sed [OPTION...] 'script' [INPUT_FILE...]

DESCRIPTION
       sed reads FILE, applies the script, and writes the result.

OPTIONS
       -i, --in-place
              edit files in place (sans afficher la sortie)

       -n, --quiet
              supprime l'affichage automatique (utile avec /pattern/p)

       -e SCRIPT, --expression=SCRIPT
              ajoute SCRIPT aux commandes a executer

       -E, --regexp-extended
              use extended regular expressions (comme grep -E)

COMMANDES DU SCRIPT (langage sed)
       s/REGEX/REPLACEMENT/[FLAGS]
              substitute. Flags : g (global, toutes les
              occurrences), i (insensitive), p (print)

       /REGEX/d
              delete les lignes qui matchent REGEX

       /REGEX/p
              print les lignes qui matchent (avec -n)

       Nd
              supprime la ligne N

       N,Md
              supprime les lignes N a M

       y/abc/xyz/
              transliteration (a->x, b->y, c->z)

EXEMPLES
       # Substitution simple
       echo "hello" | sed 's/hello/bonjour/'

       # In-place avec backup .bak
       sed -i.bak 's/foo/bar/g' fichier.txt

       # Supprime les lignes vides
       sed '/^$/d' fichier.txt

       # Affiche les lignes 5 a 10 seulement
       sed -n '5,10p' fichier.txt

       # Backreferences : inverse "Nom Prenom" en "Prenom Nom"
       sed -E 's/^([A-Z][a-z]+) ([A-Z][a-z]+)$/\2 \1/' fichier
# a) Substitution sans modifier le fichier
sed 's/ERROR/WARN/g' app.log

# b) Modifier le fichier directement (in-place)
sed -i 's/ERROR/WARN/g' app.log

# c) Supprimer les lignes commencant par #
sed '/^#/d' config.conf

Decryptage de la substitution :

sed 's/MOTIF/REMPLACEMENT/FLAGS' fichier
       ^       ^             ^
       |       |             flags : g (global), i (case-insensitive)
       |       le remplacement
       le motif (regex)

Autres operations sed :

Backreferences : dans le remplacement, \1 = premier groupe capture.

# Inverser nom prenom dans un fichier "Prenom Nom"
sed -E 's/^([A-Z][a-z]+) ([A-Z][a-z]+)$/\2 \1/' fichier.txt

Question 12 / 12 cas pratique : log Apache

Extraire toutes les IPs d'un log d'acces

Le fichier /var/log/apache2/access.log contient des lignes comme :
192.168.1.42 - - [13/May/2026:14:23:00 +0000] "GET / HTTP/1.1" 200 1234 10.0.0.5 - - [13/May/2026:14:23:05 +0000] "POST /api HTTP/1.1" 401 89 192.168.1.42 - - [13/May/2026:14:23:09 +0000] "GET /css HTTP/1.1" 200 456
a) Donnez la commande qui extrait toutes les IPs (4 nombres separes par 3 points) :
b) En plus, compter chaque IP et afficher le top 5 des plus frequentes (combiner grep + sort + uniq -c + sort + head) :
Pour extraire seulement le match : grep -oE "regex". Une IP = 4 groupes de 1 a 3 chiffres separes par des points litteraux. Attention : . est le joker, il faut l'echapper \.. Pour compter et trier : | sort | uniq -c | sort -rn | head -5.
# a) Extraire toutes les IPs (note les \. pour le point litteral)
grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" /var/log/apache2/access.log
# Plus precis (1 a 3 chiffres par groupe)
grep -oE "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" /var/log/apache2/access.log

# b) Top 5 des IPs les plus frequentes
grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" /var/log/apache2/access.log \
    | sort | uniq -c | sort -rn | head -5

Decryptage de la chaine de commandes :

Sortie attendue :

     12 192.168.1.42
      8 10.0.0.5
      5 203.0.113.7
      3 198.51.100.99
      2 192.168.1.50

Variante plus stricte (vraie IP, octets <= 255) :

# Regex precise pour octets 0-255 (complexe)
grep -oE "(25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})" log
# En pratique [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ suffit dans 99% des cas

Bilan

Ce que vous venez de pratiquer

Pour tester : regex101.com ou regexr.com

R pour recommencer.

« Retour aux mini-tests