re
qui nous permet de les utiliser. Cette leçon n’est pas un cours sur les expressions rationnelles qui représentent un sujet vaste et complexe mais simplement une introduction aux possibilités et à l’utilisation de ces expression dans un contexte Python.
Présentation des expressions régulières ou expressions rationnelles
Les expressions régulières ou expressions rationnelles ne font pas partie du langage Python en soi mais constituent un langage à part. Python nous permet d’exploiter leur puissance et fournit un support pour les expressions régulières via son module standard re
.
Les expressions régulières sont des schémas ou des motifs utilisés pour effectuer des recherches et des remplacements dans des chaines de caractères.
Ces schémas ou motifs sont tout simplement des séquences de caractères dont certains vont disposer de significations spéciales et qui vont nous servir de schéma de recherche. On les appelle également des masques de recherche.
Concrètement, les expressions régulières vont nous permettre de vérifier la présence de certains caractères ou suites de caractères dans une expression afin de valider la forme de données envoyées par l’utilisateur via une fonction input()
par exemple.
La syntaxe des expressions rationnelles
Une expression rationnelle est représentée par un motif de recherche. Ce motif de recherche va pouvoir être comparée à une ou plusieurs chaines pour déterminer les correspondances.
Un motif de recherche peut être composés de caractères “normaux”, c’est-à-dire des caractères qui ne représentent qu’eux mêmes et de caractères “spéciaux”, c’est-à-dire des caractères qui possèdent une signification spéciale et vont nous permettre de rechercher autre chose qu’eux mêmes. On appelle également ces caractères au sens spécial des “métacaractères”.
Ces caractères spéciaux font toute la puissance des expressions rationnelles puisqu’ils nous permettent de créer des motifs de recherche très précis et complexes.
Le premier caractère à connaitre est l’antislash \
qui est utilisé par les expressions rationnelles pour donner un sens spécial à certains caractères normaux ou au contraire pour neutraliser (“échapper”) le sens d’un caractère spécial et nous permettre de rechercher le caractère en soi sans qu’il exprime son sens spécial.
Ici, nous sommes déjà confrontés à un souci puisque Python utilise également l’antislash comme caractère d’échappement. Pour rechercher un antislash littéral avec une expression régulière il faudrait donc écrire \\\\
puisque chaque antislash doit être représenté par \\
dans une chaine littérale Python et que pour rechercher un antislash (qui est un caractère spécial) dans une expression rationnelle il faut écrire \\
(le premier antislash servant de caractère d’échappement pour rechercher le deuxième).
Pour éviter ce genre de situation, on utilisera une notation Python de chaines brutes plutôt que littérales. Pour cela, il suffira de préfixer la chaine avec un r
.
Ensuite, vous devez savoir que certains caractères ne vont avoir un sens spécial qu’en dehors de ce qu’on appelle des classes de caractères ou vont pouvoir avoir des sens spéciaux différents selon qu’ils soient dans des classes de caractères ou en dehors. Commençons déjà par comprendre ce qu’est une classe de caractères.
Les classes de caractères
Les classes de caractères vont nous permettre de fournir différents choix de correspondance pour un caractère en spécifiant un ensemble de caractères qui vont pouvoir être trouvés.
En d’autres termes, elles vont nous permettre de rechercher n’importe quel caractère d’une chaine qui fait partie de la classe de caractères fournie dans le masque, ce qui va rendre les expressions régulières déjà beaucoup plus puissantes et flexibles qu’une recherche classique.
Pour déclarer une classe de caractères dans notre masque de recherche, nous allons utiliser une paire de crochets [ ]
qui vont nous permettre de délimiter la classe en question.
Dans le langage des expressions régulières, de nombreux caractères vont avoir une signification spéciale et vont nous permettre de signifier qu’on recherche tel caractères ou telle séquence de caractères un certain nombre de fois ou à une certaine place dans une chaine.
Au sein des classes de caractères, seuls les caractères suivants possèdent une signification spéciale :
Métacaractère | Description |
---|---|
\ | Caractère de protection ou d’échappement qui va avoir plusieurs usages (on va pouvoir s’en servir pour donner un sens spécial à des caractères qui n’en possèdent pas ou au contraire pour neutraliser le sens spécial des métacaractères). |
^ | Si placé au tout début d’une classe, permet de nier la classe c’est-à-dire de chercher tout caractère qui n’appartient pas à la classe. |
– | Entre deux caractères, permet d’indiquer un intervalle de caractères (correspond à écrire les deux caractères et tous les caractères entre ces deux là). |
Si on souhaite rechercher le caractère représenté par l’un des métacaractères ci-dessus plutôt que de l’utiliser pour son sens spécial (par exemple si on souhaite rechercher le signe moins), il faudra alors le protéger ou « l’échapper » avec un antislash.
Notez qu’il faudra également protéger les caractères de classe (les crochets) si on souhaite les inclure pour les rechercher dans une classe de caractères car dans le cas contraire on n’aurait aucun moyen de déterminer si le caractère “]” est recherché ou si la classe est refermée par exemple.
Les classes de caractères abrégées
En plus des classes de caractères “classiques”, les expressions régulières possèdent également des éléments qu’on appelle classes de caractères abrégées et qui permettent de représenter certaines classes couramment utilisées avec une syntaxe très courte.
La syntaxe des classes abrégées utilise l’antislash suivi d’un caractère “normal” afin de lui donner dans un cas une signification spéciale. Les classes abrégées les plus intéressantes sont les suivantes (faites bien attention aux emplois de majuscules et de minuscules ici !) :
Classe abrégée | Description |
---|---|
\w | Représente tout caractère de « mot » (caractère alphanumérique + tiret bas). Équivalent à [a-zA-Z0-9_] |
\W | Représente tout caractère qui n’est pas un caractère de « mot ». Equivalent à [^a-zA- Z0-9_] |
\d | Représente un chiffre. Équivalent à [0-9] |
\D | Représente tout caractère qui n’est pas un chiffre. Équivalent à [^0-9] |
\s | Représente un caractère blanc (espace, retour chariot ou retour à la ligne) |
\S | Représente tout caractère qui n’est pas un caractère blanc |
\t | Représente une espace (tabulation) horizontale |
\v | Représente une espace verticale |
\n | Représente un saut de ligne |
Les caractères spéciaux en dehors des classe de caractères
En dehors des classes de caractères, nous avons accès à de nombreux autres caractères au sens spécial. En voici la liste ainsi que leur signification :
Métacaractère | Représente |
---|---|
. | N’importe quel caractère |
^ | Le début d’une chaine ou d’une ligne |
$ | La fin d’une chaine ou d’un ligne |
| | Une alternative : correspond au caractère à droite ou à gauche |
* | 0, 1 ou plusieurs occurrences |
+ | 1 ou plusieurs occurrences |
? | 0 ou 1 occurrence |
{…} | Un quantificateur : correspond à un nombre n d’occurences d’un caractère |
[…] | Une classe de caractères : tous les caractères énumérés dans la classe, avec possibilité de plages dont les bornes sont séparées par « -« |
(…) | Un groupe de capture : utilisée pour limiter la portée d’un masque ou d’une alternative |
Note : les expressions rationnelles possèdent également des éléments de syntaxe plus complexes comme les assertions que nous n’étudierons pas dans ce cours.
Le module Python re et ses fonctions
Maintenant que nous avons (très rapidement) parcouru les éléments de syntaxe principaux des expressions régulières, il est temps de les utiliser avec le module re
de manière pratique.
Une expression rationnelle en soi n’est qu’un motif. Nous allons donc utiliser des fonctions qui vont permettre d’effectuer des recherches de motifs dans des chaines, des remplacements, etc.
La fonction compile()
compile un motif vers une expression rationnelle compilée qu’on va pouvoir utiliser avec les méthodes match()
et search()
.
On utilisera compile()
lorsqu’on voudra sauvegarder une expression rationnelle pour la réutiliser dans un programme.
La fonction search()
permet d’analyser une chaine passée en deuxième argument à la recherche du premier emplacement où l’expression rationnelle passé en premier argument trouve une correspondance, et renvoie l’objet de correspondance trouvé ou None
si aucune position dans la chaîne ne valide le motif.
La fonction match()
prend également un schéma de recherche en premier argument et une chaine dans laquelle effectuer la recherche en deuxième argument et renvoie l’objet de correspondance trouvé si zéro ou plus caractères au début de la chaine correspondent à l’expression rationnelle ou None
si la chaîne ne correspond pas au motif.
La fonction findall()
renvoie toutes les correspondances de l’expression régulière passée en premier argument dans la chaine passée en deuxième argument qui ne se chevauchent pas, sous forme d’une liste de chaînes. Le chaîne est analysée de la gauche vers la droite, et les correspondances sont renvoyées dans l’ordre où elles sont trouvées.