Accueil » Leçon 8 - Les expressions régulières

Leçon 8 - Les expressions régulières

Objectifs de la leçon :

L'objectif de la leçon est de découvrir les expressions régulières et de les maîtriser dans le cadre du métier de l'ASR.

Les expressions régulières représentent des motifs qu'on recherche dans une chaîne de caractères.

Par exemple, on peut chercher dans un fichier :

  • les lignes qui contiennent un numéro de téléphone,
  • les lignes qui débutent par une adresse IP,
  • ...

On pourra aussi remplacer dans un fichier :

  • des dates au format américain par des dates au format français,
  • des logins écrits parfois avec des majuscules, des minuscules, des caractères spéciaux par des logins normalisés,
  • ...

Pré-requis :

La leçon 1 : afficher, saisir, les variables, les calculs.

La leçon 2 : les structures conditionnelles.

La leçon 3 : les fonctions.

La leçon 4 : les boucles.

La leçon 5 : les listes.

La leçon 6 : les fichiers. Pas indispensable mais conseillé.


Des exemples pour démarrer

Trouver un motif simple :

Exemple : Chercher dans une liste de 4 chaines celles qui contiennent la syllabe 'ou'
  • Remarquez dans le code ci-dessous la méthode search du module re :
    re.search( 'ou' , ch ) retourne true si la chaine ch contient l'expression régulière 'ou' et false sinon.
  • Lancez le code et vérifiez que les deux chaines de caractères qui contiennent 'ou' sont bien :
    • J'ai tout compris
    • Fromage ou dessert



Rechercher une chaine qui débute par un U majuscule.

Exemple : Chercher dans une liste de 4 chaines celles qui débutent par un U majuscule.
  • Remarquez dans le code ci-dessous l'expression régulière '^U' :
    On emploie l'accent circonflexe en début de RegExp pour signifier "débute par"
    re.search( '^U' , ch ) retourne true si la chaine ch débute par 'U' et false sinon.
  • Lancez le code et vérifiez que les deux chaines de caractères qui débutent par 'U' sont bien :
    • Un beau paysage
    • U123456789



Rechercher une chaine qui termine par un e minuscule.

Exemple : Chercher dans une liste de 4 chaines celles qui terminent par un e minuscule.
  • Remarquez dans le code ci-dessous l'expression régulière 'e$' :
    On emploie le symbole $ (dollar) en fin de RegExp pour signifier "termine par"
    re.search( 'e$' , ch ) retourne true si la chaine ch termine par 'e' et false sinon.
  • Lancez le code et vérifiez que les deux chaines de caractères qui terminent par 'e' sont bien :
    • Un beau paysage
    • une voiture rouge



Le point (.) est un joker, il représente n'importe quel caractère.

Exemple : Chercher dans une liste de 4 chaines celles contiennent un d et un t séparés par un caractère quelconque.
  • Remarquez dans le code ci-dessous l'expression régulière 'd.t'
    On emploie le caractère point (.) pour admettre n'importe quel caractère
    re.search( 'd.t' , ch ) retourne true si la chaine ch contient un d et un t séparés par un caractère quelconque et false sinon.
  • Lancez le code et vérifiez que les deux chaines de caractères qui matchent sont bien :
    • Il apprend très vite # l'espace est un caractère comme un autre
    • Il m'a dit de prendre le train
    • Nous avons pris date



Protéger des caractères spéciaux.

Vous l'avez compris, certains caractères ont des rôles spéciaux. On vient d'en voir 3 : ^, $ et .

Si on cherche ces caractères dans une chaine, il faut donc les protéger. Pour cela on utilise \

Exemple : Chercher dans une liste de 4 chaines celles qui contiennent un $.
  • Remarquez dans le code ci-dessous l'expression régulière '\$' :
    On emploie l'antislach (\) quand on cerhce un caractère qui joue un rôle spécial dans les expressions régulières
    re.search( '\$' , ch ) retourne true si la chaine ch contient '$' et false sinon.
  • Lancez le code et vérifiez que les trois chaines de caractères qui contiennent un '$' sont bien :
    • C'est 400 $
    • 1 $ = 0.98 €
    • Tout à moins de un $. Si vous trouvez moins cher...



Quelques petites questions avant d'aller plus loin :

Exercice à choix multiple : Chaines qui débutent par un point
Quelle est l'expression régulière pour chercher les chaines qui débutent par un point ?
Bien !

Exercice à réponse courte : Chaines qui contiennent un a et un b séparés par deux caractères quelconques
Quelle est la bonne expression régulière pour chercher les chaines qui contiennent un a et un b séparés par deux caractères quelconques ?
Bien !

Exercice à réponse courte : Chaines qui terminent par un point
Quelle est la bonne expression régulière pour chercher les chaines qui terminent par un point ?
Bien !

Ressources utiles

L'ESSENTIEL AVEC DES EXEMPLES DE BASE

Les expressions régulières représentent des motifs qu'on recherche dans une chaîne de caractères.

Chercher un motif simple :

Exemple : Chercher dans une liste de 4 chaines celles qui contiennent la syllabe 'eau'
  • Remarquez dans le code ci-dessous la méthode search du module re :
    re.search( 'eau' , ch ) retourne true si la chaine ch contient l'expression régulière 'eau' et false sinon.
  • Lancez le code et vérifiez que les deux chaines de caractères qui contiennent 'eau' sont bien :
    • J'ai un chapeau
    • Un beau soleil

  • Remarquez la sensibilité à la casse : Eau minérale ne matche pas puisque le E est en majuscule.



Rechercher au début.

Pour chercher un motif en début de chaine, on utilise l'accent circonflexe : ^.

Exemple : Chercher dans une liste de 4 chaines celles qui débutent par un 0 (chiffre 0).
  • Remarquez dans le code ci-dessous l'expression régulière '^0' :
    On emploie l'accent circonflexe en début de RegExp pour signifier "débute par"
    re.search( '^0' , ch ) retourne true si la chaine ch débute par '0' et false sinon.
  • Lancez le code et vérifiez que les deux chaines de caractères qui débutent par '0' sont bien :
    • 01 23 45 67 89
    • 007, my name is Bond, James Bond



Rechercher à la fin.

Pour chercher un motif en fin de chaine, on utilise le dollar : $.

Exemple : Chercher dans une liste de 4 chaines celles qui terminent par un r minuscule.
  • Remarquez dans le code ci-dessous l'expression régulière 'r$' :
    On emploie le symbole $ (dollar) en fin de RegExp pour signifier "termine par"
    re.search( 'r$' , ch ) retourne true si la chaine ch termine par 'r' et false sinon.
  • Lancez le code et vérifiez que la seule chaine de caractères qui termine par 'r' est bien :
    • Laissez passer



Rechercher un caractère spécial.

Les caractères spéciaux des expressions régulières sont ^ $ / . \ ? + * ( ) [ ] { } |
Pour chercher un de ces caractères, il faut le précéder d'un \

Exemple : Chercher dans une liste de 4 chaines celles qui contiennent le signe +.
  • Remarquez dans le code ci-dessous l'expression régulière '\+' :
    Quand on cherche un caractère spécial dans une expression régulière, il faut le protéger grâce à l'antislash : \
    re.search( '\+' , ch ) retourne true si la chaine ch contient + et false sinon.
  • Lancez le code et vérifiez que les 3 chaines de caractères qui contiennent + sont bien :
    • C'est + ou - bien
    • 3 + 4 = 7
    • @+



Rechercher un motif OU un autre.

Le OU, c'est  |

Exemple : Chercher dans une liste de 4 chaines celles qui contiennent "ce" OU "se".
  • Remarquez dans le code ci-dessous l'expression régulière 'ce|se':
    Elle signifie qu'on cherche les chaines qui contiennent ce ou se.
    re.search( 'ce|se' , ch ) retourne true si la chaine ch contient ce OU se et false sinon.
  • Lancez le code et vérifiez que les 3 chaines de caractères qui contiennent ce OU se sont bien :
    • Laisse tomber !
    • J'aime cet endroit
    • Cochez la bonne case



Ignorer la casse.

Si on veur ignorer la casse dans une recherche, c'est à dire ne pas se préoccuper des majuscules et des minuscules, il faut utiliser  re.IGNORECASE

Exemple : Chercher dans une liste de 4 chaines celles qui contiennent "ce" en ignorant la casse.
  • Remarquez dans le code ci-dessous l'instruction re.search( 'ce' , ch , re.IGNORECASE) :
    Elle signifie qu'on cherche les chaines qui contiennent ce en ignorant la casse, c'est à dire ce OU Ce ou cE ou CE.
    re.search( 'ce' , ch , re.IGNORECASE) retourne true si la chaine ch contient ce en ignorant la casse et false sinon.
  • Lancez le code et vérifiez que les 3 chaines de caractères qui contiennent ce en ignorant la casse sont bien :
    • Ce code respecte les bonnes pratiques
    • J'aime cet endroit
    • La CEE est la Communauté Economique Européenne



Autoriser plusieurs choix pour un même caractère.

On dispose des crochets [ ] qui permettent de donner la liste des caractères autorisés.

Exemple : Chercher dans une liste de 4 chaines celles qui contiennent une voyelle quelconque entourée par un s et un t.
  • Remarquez dans le code ci-dessous l'instruction re.search( 's[aeiouy]t' , ch ) :
    Elle signifie qu'on cherche les chaines qui contiennent une voyelle quelconque entourée par un s et un t.
    Notez bien [aeiouy] qui autorise un caractère parmi les 6 voyelles proposées.
    re.search( 's[aeiouy]t' , ch ) retourne true si la chaine ch contient une voyelle quelconque entourée par un s et un t et false sinon.
  • Lancez le code et vérifiez que les 2 chaines de caractères qui matchent sont bien :
    • L'autoroute est saturée
    • Ce site est vraiment bien fait



Autoriser plusieurs choix pour un même caractère, des listes déjà toutes prêtes.

Dans les crochets [ ], on peut faire référence à des listes pré-établies :

  • [A-Z] signifie "toutes les majuscules autorisées"
  • [a-z] signifie "toutes les minuscules autorisées"
  • [0-9] signifie "tous les chiffres autorisés"
  • mais aussi  : [B-F] signifie "toutes les majuscules de B à F autorisées"
  • ou bien entendu : [A-Za-z], "toutes les lettres utilisées" (liste de listes)
  • ... etc...

Exemple : Chercher dans une liste de 4 chaines celles qui débutent par une majuscule suivie d'un chiffre.
  • Remarquez dans le code ci-dessous l'instruction re.search( '^[A-Z][0-9]' , ch ) :
    Elle signifie qu'on cherche les chaines qui débutent par une majuscule suivie d'un chiffre.
    • ^ pour débute.
    • [A-Z] pour une majuscule comme premier caractère.
    • [0-9] pour un chiffre en deuxième caractère.

  • Lancez le code et vérifiez que les 2 chaines de caractères qui matchent sont bien :
    • E15 est une autoroute européenne !
    • H2O est le symbole chimique de l'eau



Des raccourcis pour certaines listes très utilisées.

Dans les crochets [ ], on peut faire référence à des listes pré-établies :

  • \d n'importe quel chiffre <-> [0-9]
  • \D tout sauf un chiffre
  • \s un espace, une tabulation ou un retour à la ligne
  • \S tout sauf un espace, une tabulation ou un retour à la ligne
  • \w un mot : toute suite de caractères délimitée par des espaces, tabulation ou retour à la ligne

Exemple : Chercher dans une liste de 4 chaines celles qui contiennent 2 chiffres séparés par un caractère qui n'est pas un chiffre.
  • Remarquez dans le code ci-dessous l'instruction re.search( '\d\D\d' , ch ) :
    Elle signifie qu'on cherche les chaines qui contiennent 2 chiffres séparés par un caractère qui n'est pas un chiffre.
    • \d le premier chiffre,
    • suivi \D, tout sauf un chiffre,
    • et de \d, encore un chiffre.

  • Lancez le code et vérifiez que les 3 chaines de caractères qui matchent sont bien :
    • Le virus H1N1 est redoutable
    • Nous sommes le 10 09 2015
    • x1E23bn456 est une bonne clé de cryptage



Eviter un caractère, l'opérateur sauf : [^].

Quand les crochets [ ] débutent par ^, la liste des caractères suivants représente les caractères non autorisés :

Exemple : Chercher dans une liste de 4 chaines celles qui contiennent un o qui n'est pas suivi d'un i.
  • Remarquez dans le code ci-dessous l'instruction re.search( 'o[^i]' , ch ) :
    Elle signifie qu'on cherche les chaines qui contiennent un o qui n'est pas suivi d'un i.
  • Lancez le code et vérifiez que les 3 chaines de caractères qui matchent sont bien :
    • Les oiseaux volent dans le ciel
    • Allo, qui est à l'appareil ? C'est toi ?
    • il n'est ni gros ni maigre

On a surligné les sous-chaines qui assurent la correspondance. Remarquez bien au passage que d'un point de vue linguistique, "contenir un o qui n'est pas suivi d'un i" n'est pas équivalent à "ne pas contenir la syllabe oi".



Les quantificateurs :
Comme leur nom l'indique, les quantificateurs s'intéressent au nombre de fois qu'on va trouver tel ou tel caractère (ou groupe de caractères), il y en a quatre.

  • Le ? signifiera "au plus une fois".
  • Le + signifiera "au moins une fois".
  • Le * signifiera "0, une ou plusieurs fois".
  • Grâce aux accolades, on va fixer un nombre minimum ou maximum d'apparitions.


Le quantificateur ?, il signifie "au plus une fois".

Exemple : Chercher dans une liste de 4 chaines celles qui contiennent deux chiffres encadrant une lettre majuscule au plus.
  • Le titre de l'exemple signifie qu'on cherche dans la chaine une séquence de 2 chiffres ou une séquence de 2 chiffres séparés par une seule majuscule.
  • Remarquez dans le code ci-dessous l'instruction re.search( '\d[A-Z]?\d' , ch ) :
    Elle signifie qu'on cherche les chaines qui contiennent deux chiffres encadrant une lettre majuscule au plus.
    • \d, le premier chiffre de la séquence
    • [A-Z]? : il est suivi de zéro ou d'une majuscule
    • \d, puis d'un deuxième chiffre

  • Lancez le code et vérifiez que les 3 chaines de caractères qui matchent sont bien :
    • Nous sommes le 10 novembre
    • Le virus H1N1 est redoutable
    • La référence 4i52E est valable


Les quantificateurs quantifient ce qui les précède et non ce qui les suit !!! 
Dans l'exemple précédent, le ? donne une information sur [A-Z].
Donc on commence à découvrir ici des RegExp un peu complexes. D'un point de vue linguistique, on n'a pas l'habitude qu'une information d'un phrase vienne modifier ce qui la précède.
Ceci nous force à faire des retour arrière auxquels notre esprit de lecteur n'est pas habitué.


Le quantificateur +, il signifie "au moins une fois".

Exemple : Chercher dans une liste de 4 chaines celles qui contiennent deux chiffres encadrant une lettre majuscule au moins.
  • Remarquez dans le code ci-dessous l'instruction re.search( '\d[A-Z]+\d' , ch ) :
    Elle signifie qu'on cherche les chaines qui contiennent deux chiffres séparés par une ou plusieurs majuscules .
    • \d, le premier chiffre de la séquence
    • [A-Z]+ : il est suivi de une ou plusieurs majuscules
    • \d, puis d'un deuxième chiffre

  • Lancez le code et vérifiez que les 2 chaines de caractères qui matchent sont bien :
    • Le virus H1N1 est redoutable
    • La référence 4i1-4FEZ3-3 est valable


Le quantificateur *, il signifie "zéro, une ou plusieurs fois".

Exemple : Chercher dans une liste de 4 chaines celles qui contiennent une minuscule et un chiffre dans cet ordre séparés par zéro, un ou plusieurs tirets.
  • Remarquez dans le code ci-dessous l'instruction re.search( '[a-z]-*\d' , ch ) :
    Elle signifie qu'on cherche les chaines qui contiennent une minuscule et un chiffre séparés par zéro, un ou plusieurs tirets.
    • [a-z], la minuscule
    • -* : zéro, un ou plusieurs tirets
    • \d, le chiffre

  • Lancez le code et vérifiez que les 3 chaines de caractères qui matchent sont bien :
    • La référence 4i52E est valable
    • La référence 4i-52E est valable
    • La référence 4i------52E est valable


Les quantificateurs accolades :

Le quantificateur { } indique un nombre de répétitions cherchées dans la chaîne

  • {k} : on cherche k fois le caractère précédent :
    'ba{2}d' → on va trouver baad, mais pas bd, bad, baaad etc...
  • {k, } : on cherche au moins k fois le caractère précédent :
    'ba{2,}d' → on va trouver baad, baaad, baaaad mais pas bd ni bad
  • { ,k} : on cherche au plus k fois le caractère :
    'ba{,2}d' → on va trouver bd, bad, baad, mais pas baaad...
  • {k,l} : on cherche entre k et l fois le caractère :
    'ba{2,4}d' → on va trouver baad, baaad, baaaad mais pas bd, bad, baaaaad...

Exemple : Chercher dans une liste de 6 chaines celles qui contiennent une séquence de 2 à 4 chiffres encadrée par des @.
  • Remarquez dans le code ci-dessous l'instruction re.search( '@\d{2,4}@ , ch ) :
    Elle signifie qu'on cherche les chaines qui contiennent une minuscule et un chiffre séparés par zéro, un ou plusieurs tirets.
    • @, la première arobase
    • \d{2,4}, une séquence de 2 à 4 chiffres
    • @, la deuxième arobase

  • Lancez le code et vérifiez que les 3 chaines de caractères qui matchent sont bien :
    • La référence @12@ est valable
    • La référence @123@ est valable
    • La référence @1234@ est valable



Le point (.) est un joker, il représente n'importe quel caractère.

Exemple : Chercher dans une liste de 6 chaines celles qui débutent par une majuscule et qui terminent par une minuscule.
  • Il faut comprendre l'implicite du titre : la chaîne débute par une majuscule et termine par une minuscule. Donc, entre les deux, on a n'importe quoi, en n'importe quelle quantité.
  • Remarquez dans le code ci-dessous l'expression régulière '^[A-Z].*[a-z]$'
    • ^[A-Z] : on débute par une majuscule
    • .* : n'importe quoi (le .), en n'importe quelle quantité (le *)
    • [a-z]$ : on termine par une minuscule

  • Lancez le code et vérifiez que les 4 chaines de caractères qui matchent sont bien :
    • Il apprend très vite
    • Ton tel est le 01-23-45-67-89. Je le note
    • Ho
    • Nous avons pris date



Les prenthèses servent à grouper les caractères.

Exemple : Chercher dans une liste de 4 chaines celles qui contiennent au moins 2 syllabes "to" successives.
  • Remarquez dans le code ci-dessous l'expression régulière '(to){2,}'
    • (to) : un groupe de 2 caractères
    • {2,} : quantifié au moins 2 fois

  • Lancez le code et vérifiez que les 2 chaines de caractères qui matchent sont bien :
    • il est content toto
    • Le cirque tototo vous accueille !

Quelques exemples plus poussés


Chercher un numéro de téléphone.

Exemple : Chercher dans une liste de 6 chaines celles qui contiennent un numéro de téléphone au format 01 23 45 67 89.
  • Remarquez dans le code ci-dessous l'expression régulière '(\d\d ){4}\d\d'
    • (\d\d ){4} : un groupe composé de 2 chiffres et un espace répété 4 fois.
    • \d\d : les deux derniers chiffre

  • Lancez le code et vérifiez que les 4 chaines de caractères qui matchent sont bien :
    • Ton tel est le 01 23 45 67 89. Je le note
    • Ton tel est le 01 23 45 67 89 10. Bizarre !
    • 01 23 45 67 89, OK !
    • Voilà son tel : 01 23 45 67 89

  • Remarquez qu'on matche bien les chaines débutant et terminant par des numéros au bon format. C'est une bonne habitude à prendre de tester ses RegExp sur des débuts ou fin de chaine. C'est souvent là que ça bugue.

 

Des pièges à éviter


Oublier de protéger les caractères spéciaux

Exemple : Mal chercher les adresses mail du domaine iutsf.org
Dans la RegExp 'iutsf.org', on n'a pas protégé le point qui est un joker. On laisse donc passer les deux dernières fausses adresses du domaine iutsf.org

Exemple : Bien chercher les adresses mail du domaine iutsf.org
En protégeant le joker . c'est mieux !
La bonne RegExp est donc 'iutsf\.org'


Le rôle de p dans le quantificateur {n,p}

Exemple : Attention au rôle de p dans le quantificateur {n,p}
  • On peut penser que la chaine "100000001" ne va pas correspondre à la RegExp '0{3,5}'. Mais comme le montre le premier affichage de cet exemple, il n'en est rien. Dès que le système rencontre les 3 premiers zéros en bleu, il ne lit plus la suite et sait que la chaîne matche.
  • Idem pour les deux chaines suivantes

Exemple : Attention au rôle de p dans le quantificateur {n,p}
  • Si on veut utiliser le p du quantificateur {n,p}, c'est à dire le max, il faut que les caractères cherchés soient encadrés par d'autres caractères que la RegExp interdit, par exemple la regExp \D0{3,5}\D cherche une chaine contenant de 3 à 5 fois le chiffre 0 encadrés par un caractère qui n'est pas un chiffre. C'est pour cela que le deuxième affichage montre que la chaine ne matche pas (7 est un chiffre).
  • Avec la chaine "A00000B58 est un bon identifiant", ça matche. On a bien entre 3 et 5 zéros (5) et ils sont encadrés par des caractères qui ne sont pas des chiffres A et B.


Chercher une chaine qui ne contient pas de r

Exemple : Fausse recherche de chaines sans r
On peut penser que la chaine "Brrrrrrrrrrr, il fait froid" ne va pas matcher la RegEXp '[^r]' (n'importe quel caractère sauf le r. Evidemment il n'en est rien puisque dès que le système rencontre B, il sait que ça matche et ne lit plus la suite

Exemple : Vraie recherche de chaines sans r
Il faut bien mesurer que d'un point de vue sémantique, chercher une chaine qui ne contient pas de r est différent de chercher une chaine qui contient un caractère autre que r.
Pour chercher une chaine sans r, il faut chercher une chaine qui commence et qui finit par des caractères autres que r, en nombre quelconque : '^[^r]*$'


Mettre des espaces dans les expressions régulières pour les rendre plus lisibles

Exemple : Space bug
Pensez qu'insérer un espace dans une RegExp c'est chercher cet espace !
Donc, en général, il faut "tout laisser collé", ce qui rend le décryptage assez malaisé... Mais c'est comme ça.
Voyez ce qui arrive quand on insère un espace. Ici on cherchait les chaines contenant au moins 2 chiffres suivis du caractère a.
En insérant un espace entre les 2 chiffres et le a, c'est à dire en écrivant '\\d{2,} a' au lieu de '\\d{2,}a', on ne trouve pas les deux premières chaines qui correspondaient alors qu'on trouve la 3 ème qui ne correspond pas..

Exemple : Sans espace maintenant !
  C'est rectifié !

Bon à savoir


La méthode group.

Quand on cherche des groupes dans une regexp, c'est à dire qu'on a utilisé des parenthèses, les groupes trouvés sont numérotés et réutilisables par la suite via la méthode group.

Vite un exemple !

Exemple : Découper une date et récupérer ses constituants.
 
La méthode search retourne un objet qu'on peut utiliser.
Cet objet possède notamment la méthode group qui permet de retrouver les groupes qu'on a isolés avec des parenthèses, comme ci-dessous.



La méthode sub.

La méthode sub permet de remplacer une regexp par une autre dans une chaine de caractères.

Un exemple simple :

Exemple : Remplacer les "eau" par des "au".

Observez le code ci-dessous, la méthode sub admet 3 arguments
sub('eau','au',ch) :
  • 'eau' : la regexp à remplacer
  • 'au' : la regexp de remplacement
  • ch : la chaine initiale

La chaine initiale n'est pas modifiée ! La méthode sub retourne la chaine modifiée.
 


Un exemple plus élaboré :

Plus fort avec sub : remplacer des tirets pas des slash dans une date.

Il faut savoir que les groupes déterminés par des parenthèses sont numérotés, même sans utiliser la méthode group.
Les groupes sont référencés \1 \2 \3 ...par ordre d'apparition.
Vous allez comprendre avec l'exemple suivant.

Exemple : Remplacer des tirets pas des slash dans une date.

Ici on cherche une date avec des tirets : (\d\d)-(\d\d)-(\d\d\d\d).
Puis on remplace les tirets par des slash : \\1/\\2/\\3
 
Comme les numéros des groupes débutent par des \, il faut aussi protéger le caractère spécial \ ... par un \
L'aspirine est dans le tiroir de droite de la commode au fond du couloir....
Vous remarquerez au passage que le tiret de Jean-Luc n'a pas été modifié.
 


Encore plus fort.... :

On peut ne pas utiliser les numéros des groupes mais donner nos propres noms à nos groupes, ça rend le code plus lisible !
Pour nommer un groupe, il faut faire suivre la parenthèse ouvrant le groupe :
  • d'un point d'interrogation,
  • d'un P majuscule
  • et du nom du groupe entre chevrons <>.

Dans l'expression de remplacement, il faut précéder le nom du groupe entre chevrons par \g (pour groupe)

Exemple : Remplacer des tirets pas des slash dans une date.

  • Le premier groupe de deux chiffres s'appelle jour : (?P<jour>\d\d)
  • Le deuxième groupe de deux chiffres s'appelle mois : (?P<mois>\d\d)
  • Le troisième groupe de quatre chiffres s'appelle annee : (?P<annee>\d\d\d\d)

Puis on remplace les tirets par des slash : '\g<jour>/\g<mois>/\g<annee>'

Qui a dit que ça rendait le code plus lisible ???
Vous reprendrez bien une petite aspirine pour la route...


La méthode findall.

Comme son nom l'indique, elle retourne la liste de toutes les occurrences de la regexp rencontrée dans une chaine de caractères.

Exemple : Trouver toutes les occurrences du motif -\d\d- dans une chaine.

On cherche donc dans une chaine toutes les sous-chaines de la forme -15- ou -87- etc.. Un tiret, 2 chiffres, un tiret.


Compiler une regexp.

On peut compiler une regexp avec la méthode compile, c'est utile quand elle doit resservir.

Cela permet de lui donner un nom pour alléger le code.

C'est bien expliqué sur Openclassrooms

Le quizz

Exercice à réponse courte : Chercher un motif simple
Donner la RegExp pour chercher le motif "oui".
Donner la réponse entre quotes.
Bien !

Exercice à réponse courte : Chercher un motif au début
Donner la RegExp pour chercher les chaines qui débutent par une majuscule.
Donner la réponse entre quotes.
Bien !

Exercice à réponse courte : Chercher un motif à la fin
Donner la RegExp pour chercher les chaines qui terminent par un point.
Donner la réponse entre quotes.
Bien !

Exercice à réponse courte : Chercher un caractère spécial
Donner la RegExp pour chercher les chaines qui terminent par un point d'interrogation.
Donner la réponse entre quotes.
Bien !

Exercice à réponse courte : Chercher un caractère spécial
Donner la RegExp pour chercher les chaines qui contiennent le motif "\\(Linux\\)".
Donner la réponse en quotes.
Bien !

Exercice à choix multiple : Chercher un caractère spécial
Donner la RegExp pour chercher les chaines qui terminent par le motif "[...]".
Bien !

Exercice à choix multiple : Chercher un motif ou un autre
Donner la RegExp pour chercher les chaines qui débutent par B ou D.
Bien !

Exercice à choix multiple : Ignorer la casse
Quelle est la bonne syntaxe pour savoir si la chaine L termine par jpg ou JPG ou Jpg ou plus généralement, par les 8 combinaisons possibles de jpg en acceptant majuscules ou minuscules ?
Bien !

Exercice à choix multiple : Autoriser plusieurs caractères
Quelle est la bonne syntaxe pour savoir si la chaine L contient un "ou" ou un "oi" ou un "on" ou un "om" ?
Bien !

Exercice à choix multiple : Les listes standards
Quelle chaine matche l'expression régulière '^[A-Z]|[0-9]$' ?
Bien !

Exercice à choix multiple : Des raccourcis classiques
Quelle chaine matche l'expression régulière '\s\d\D\d\s' ?
Bien !

Exercice à choix multiple : L'opérateur sauf
Quelle chaine ne matche pas l'expression régulière '^[^a-z]' ?
Bien !

Exercice à choix multiple : Le quantificateur ?
Quelle chaine matche l'expression régulière 'html?$' ?
Bien !

Exercice à choix multiple : Le quantificateur +
Quelle chaine matche l'expression régulière '^[A-Z][0-9]+' ?
Bien !

Exercice à choix multiple : Le quantificateur *
Quelle chaine ne matche pas l'expression régulière '\d\D*\d' ?
Bien !

Exercice à choix multiple : Les accolades
Quelle chaine ne matche pas l'expression régulière '[A-Z]\d{3,5}\s' ?
Bien !

Exercice à choix multiple : La caractère .
Quelle chaine ne matche pas l'expression régulière '^[A-Z].*\.$' ?
Bien !

Exercice à choix multiple : Grouper des caractères
Quelle chaine matche l'expression régulière '\D(\d-\d){3}\D' ?
Bien !

Questions souvent posées


J'ai vu sur des sites des chaines de caractères débutant pas la lettre r avant les guillemets, c'est quoi ?

Il s'agit des raw-strings, des chaines brutes dans lesquelles tous les caractères sont traités pour ce qu'ils sont. Les caractères d'échappement sont ignorés.

C'est assez bien expliqué ici : http://sametmax.com/comment-marchent-les-raw-strings-en-python/

Cela n'a pas de rapport direct avec les RegExp mais ça simplifie leur écriture....

Exemple : Chaine avec ou sans r

Voyez la différence par vous-même !


Je ne sais pas comment dire "qui ne contiennent que ..." 

Il faut remplacer l'expression par "commencent et terminent par..."

Exemple : Chaine qui ne contiennent que des u et des t

Si vous cherchez des chaines qui ne contiennent que des u et des t, il faut qu'elles débutent par un u ou un t, et qu'elles terminent éventuellement par une alternance de u et de t ;-).

Exemples de questions de cours

  • Décrire le but des expressions régulières.
  • Décrire l'intérêt des expressions régulières pour l'ASSR.
  • Donner 5 règles.

Des exercices pour s'entraîner

Exercice de code : Chercher des nombres décimaux

Ecrire un programme qui vérifie qu'une saisie est un nombre décimal
Formats autorisés :
  • 0.568
  • 25
  • 15.6587

Le format .568 n'est pas autorisé.
Le programme attend la saisie du nombre et affiche un résultat sous la forme :

8.48 est un nombre décimal
ou
963 est un nombre décimal
ou
B52 n'est pas un nombre décimal
 

Vous pouvez entrer des données pour le programme dans la boîte ci-dessous.

Exercice de code : Chercher des chaines blanches

Codez la RegExp entre quottes pour ne faire apparaître que les deux chaines blanches de la liste, c'est à dire celles qui contiennent un ou plusieurs espaces entre les guillemets.
Vous devrez obtenir la sortie suivante :
 La chaine "      " est une chaine blanche
La chaine " " est une chaine blanche
 

Vous pouvez entrer des données pour le programme dans la boîte ci-dessous.

Exercice de code : Chercher des chaines contenant 6 fois la lettre e, pas nécessairement contiguës

Codez la RegExp entre quottes pour ne faire apparaître que les chaines qui contiennent exactement 6 fois la lettre e.
 ate  errt e ttu e rrtee rt
eeeeee
etuureee ko ee rty
sqdsrgeeeee rte
eeeeee gtry
dsdfqs eeeeee
 

Vous pouvez entrer des données pour le programme dans la boîte ci-dessous.

Un résumé produit par des étudiants

Voilà deux résumés de la leçon. Aucun d'eux n'est totalement satisfaisant mais ils sont complémentaires.

Résumé du chapitre 8

Autre résumé du chapitre 8

Le premier a été réalisé par Jorane CONGIO et Fabrice EDGARD, promo 2016-2017.

Le deuxième par Oliver PARKER, promo 2016-2017.

On dit souvent matche l'expression régulière
On dit souvent matche l'expression régulière