Python RegEx : comment fonctionnent les expressions régulières du célèbre langage de programmation ?

Les Python RegEx, ou expressions régulières, peuvent être utilisées avec le langage après l’importation du package intégré « re », qui permet de rechercher des modèles spécifiques dans les chaînes de caractères.

Python RegEx : de quoi s’agit-il exactement ?

Le terme « RegEx » désigne, en abrégé, les expressions régulières. Ces chaînes de caractères permettent de définir des modèles de recherche spécifiques. Vous pouvez les utiliser pour appliquer ces modèles de recherche aux chaînes en Python. Les Python RegEx fonctionnent selon une syntaxe et une sémantique qui leur sont propres.

Note

Les expressions régulières relèvent d’une technique de programmation avancée, présentée en détail dans quelques tutoriels Python. Si les techniques de programmation avancée en Python vous intéressent, les articles suivants peuvent vous permettre d’aller plus loin :

Domaines d’utilisation des Python RegEx

Les expressions régulières sont souvent utilisées pour vérifier que les données renseignées par les utilisateurs d’un programme respectent bien le format prescrit.

L’exemple le plus connu de l’utilisation de RegEx, qui vous est certainement familier, se rapporte à la création de mots de passe, ceux-ci devant souvent contenir au moins une lettre majuscule, au moins un chiffre, etc. Les Python RegEx peuvent être utilisées à cet effet ; elles permettent de vérifier que votre saisie respecte les instructions qui vous ont été données.

De la même manière, les expressions régulières sont fréquemment utilisées dans le cadre du remplissage de formulaires Web, toujours pour vérifier la validité des données renseignées par l’utilisateur. Elles peuvent notamment permettre de déterminer si le format de l’adresse email saisie par l’utilisateur est bien valide.

Conseil

Si vous utilisez Python pour votre projet Web, les expressions régulières peuvent plus d’une fois vous être utiles. L’outil Deploy Now proposé par IONOS peut lui aussi vous être d’une grande aide ; utilisez-le pour concevoir et déployer vos projets Web en passant directement par GitHub.

Syntaxe et sémantique des Python RegEx

Les expressions régulières contiennent des éléments appelés « métacaractères». Chacun de ces caractères revêt une signification bien précise dans le cadre des Python RegEx. Le tableau ci-dessous vous donne un aperçu des principaux métacaractères, tous étant accompagnés de leur signification et d’un exemple :

Caractère Signification Exemple
. Représente n’importe quel caractère à l’exception de « \n » (nouvelle ligne) « bo….r » -> trouve toutes les chaînes de quatre caractères quelconques encadrés par « bo » au début et « r » à la fin, par exemple « bonjour »
[] Trouve toutes les lettres spécifiées entre les deux crochets « [a-e] » -> trouve toutes les lettres minuscules comprises entre « a » et « e »
^ Vérifie si la chaîne commence bien par le caractère requis ou la chaîne de caractères spécifiée « ^bonjour » -> vérifie si la chaîne commence bien par « bonjour »
$ Vérifie si la chaîne se termine bien par le caractère requis ou la chaîne de caractères spécifiée « $monde » -> vérifie si la chaîne se termine bien par « monde »
* Représente l’absence d’occurrence d’un caractère ou la présence de plusieurs occurrences « a* » -> cible la présence de plusieurs « a » ou l’absence de « a »
+ Représente une ou plusieurs occurrences d’un caractère « a+ » -> cible au moins une occurrence du caractère « a »
? Représente l’absence d’occurrence d’un caractère ou la présence d’une occurrence « a? » -> cible la présence d’un « a » ou l’absence de « a »
{} Vérifie si un caractère apparaît autant de fois que le nombre spécifié entre accolades « car{2}é » -> cible la chaîne « carré »

Classes de caractères

Les classes de caractères sont particulièrement importantes pour la majorité des Python RegEx ; il est donc utile de s’y intéresser d’un peu plus près. Les classes de caractères sont des modèles de RegEx qui commencent et se terminent par des crochets. Le tableau ci-dessus contient déjà un exemple de classe de caractères, celle-ci permettant de trouver toutes les lettres minuscules comprises entre « a » et « e ». Nous allons maintenant vous présenter rapidement les cas d’utilisation courants des classes de caractères associées aux Python RegEx :

Classe de caractères Signification
[abc] Cherche si l’un des caractères spécifiés entre les crochets (ici « a », « b » ou « c ») apparaît dans une chaîne de caractères
[^abc] Cible tous les caractères n’ayant pas été spécifiés entre les crochets
[a-z] Cible toutes les lettres minuscules comprises entre « a » et « z »
[a-zA-Z] Cible toutes les lettres comprises entre « a » et « z », qu’elles soient majuscules ou minuscules
[0-9] Cible tous les chiffres compris entre 0 et 9
[1-5][0-9] Cible tous les nombres compris entre 10 et 59

Comme vous pouvez le voir, les classes de caractères constituent un outil pour diverses expressions régulières. Attention : si vous souhaitez utiliser des classes de caractères, vous devez savoir que les métacaractères que nous vous avons présentés ci-dessus n’ont aucune signification spécifique lorsqu’ils se trouvent entre crochets. Ainsi, la classe de caractères « [] » ciblerait tous les symboles « » dans la chaîne de caractères concernée.

Séquences

En plus des métacaractères dont nous avons déjà parlé, les Python RegEx vous permettent d’utiliser des séquences spéciales et prédéfinies afin de créer des modèles de recherche précis.

Séquence Signification Exemple
\A Cible la chaîne de caractères spécifiée lorsqu’elle se trouve au début d’une chaîne « \ALundi »
  • Cible la chaîne « Lundi est une belle journée »
  • Ne cible pas la chaîne « Nous sommes lundi »
\b Cible la chaîne de caractères spécifiée lorsqu’elle se trouve au début ou à la fin d’un mot « \bla »
  • Cible la chaîne « Appelle-la »
  • Cible la chaîne « Larme »
  • Ne cible pas la chaîne « Hilarant » « la\b »
  • Cible la chaîne « Gorgonzola »
  • Cible la chaîne « Il grommela quelques mots »
  • Ne cible pas la chaîne « Alarme »
\B Cible la chaîne de caractères spécifiée lorsqu’elle ne se trouve ni au début ni à la fin d’un mot (contrairement à la séquence « \b ») « \Bla »br>- Ne cible pas la chaîne « Appelle-la »
  • Ne cible pas la chaîne « Larme »
  • Cible la chaîne « Hilarant » « la\B »
  • Ne cible pas la chaîne « Gorgonzola »
  • Ne cible pas la chaîne « Il grommela quelques mots »
  • Cible la chaîne « Alarme »
\d Cible tous les chiffres compris entre 0 et 9 (comme la classe de caractères « [0-9] ») « 123 »
  • « \d » trouve trois correspondances pour 1, 2 et 3
\D Cible tous les caractères ne correspondant pas à des chiffres (comme la classe de caractères « [^0-9] ») « 123acb& »
  • « \D » trouve quatre correspondances pour « a », « c », « b » et « & »
\s Cible les chaînes de caractères contenant un espace « RegEx Python »
  • « \s » cible cette chaîne, car elle contient un espace
\S Cible les chaînes de caractères ne contenant aucun espace (contrairement à la séquence « \s ») « RegEx Python »
  • « \S » ne cible pas cette chaîne, car elle contient un espace
\w Cible tous les caractères alphanumériques « 1abc$%3 »
  • « \w » trouve cinq correspondances pour 1, « a », « b », « c » et 3
\W Cible tous les caractères n’étant pas alphanumériques (contrairement à la séquence « \w ») « 1abc$%3 »
  • « \W » trouve deux correspondances pour « $ » et « % »
\Z Cible la chaîne de caractères spécifiée lorsqu’elle se trouve à la fin d’une chaîne « Python\Z »
  • Cible la chaîne « Python RegEx »
  • Ne cible pas la chaîne « Python et les RegEx »

Fonctions relatives à l’utilisation de Python RegEx

Pour utiliser des Python RegEx, vous pouvez faire appel à plusieurs fonctions prédéfinies. Vous trouverez celles-ci dans un module Python nommé « re » ; il vous faudra donc l’importer avant de travailler avec des expressions régulières :

import re
Python

re.findall()

La fonction findall() est la plus importante pour tirer parti des Python RegEx. À partir d’un modèle de recherche et d’une chaîne de caractères Python, elle renvoie une liste Python ; composée de chaînes de caractères, elle contient toutes les correspondances dans l’ordre dans lequel ces dernières ont été trouvées. Si elle ne relève aucune correspondance, la fonction findall renvoie une liste vide.

Vous trouverez ci-dessous un exemple de code permettant d’illustrer cette fonction :

import re
string = "python 3.0"
regex = "\D"
résultat= re.findall(regex, string)
print(résultat)
Python

L’extrait de code ci-dessus permet d’importer le module « re » (comme nous vous l’avons déjà indiqué). La chaîne de caractères python 3.0 est ensuite renseignée dans la variable appelée « string ». Grâce au tableau des séquences, vous connaissez déjà le modèle de recherche enregistré dans la variable nommée « regex » : il cible tous les caractères ne correspondant pas à des chiffres. Cette mise en correspondance s’effectue à l’aide de la fonction findall(), qui utilise le modèle de recherche et la chaîne de caractères à analyser en tant que paramètres de transfert. La liste ainsi renvoyée par la fonction atterrit dans la variable appelée « résultat » ; vous pouvez appeler la fonction print de Python pour l’afficher à l’écran. Le résultat se présente alors ainsi :

['p', 'y', 't', 'h', 'o', 'n', ' ', '. ']

La liste contient tous les caractères de la chaîne, exception faite des chiffres. Attention : les espaces étant également considérées comme des caractères, il est normal qu’elles apparaissent dans cette liste.

re.sub()

Avec la fonction sub(), vous pouvez remplacer toutes les correspondances par le texte de votre choix. À l’instar de findall(), celle-ci a recours à une expression régulière en tant que premier paramètre. Le texte par lequel vous souhaitez remplacer les correspondances doit quant à lui constituer le deuxième paramètre de transfert. Le troisième paramètre de la fonction correspond à la chaîne de caractères à rechercher. Si vous ne voulez remplacer toutes les correspondances, mais seulement certaines d’entre elles, il vous suffit de spécifier un quatrième paramètre de transfert ; il doit s’agir d’un nombre servant à indiquer les correspondances devant être remplacées (en commençant par la première).

Pour mieux comprendre la marche à suivre, étudiez l’exemple de code ci-dessous :

import re
string = "python est un excellent langage de programmation"
regex = "\s"
résultat1 = re.sub(regex, "0", string)
print(résultat1)
résultat2 = re.sub(regex, "0", string, 2)
print(résultat2)
Python

Le module appelé « re » est à nouveau importé, puis une chaîne de caractères est spécifiée dans la variable string. À nouveau, vous connaissez déjà le modèle de recherche qu’il convient d’appliquer ici : celui-ci cible toutes les espaces au sein d’une chaîne de caractères.

Vous devez ensuite appeler deux fois la fonction sub, de façon assez similaire : le premier appel de fonction doit permettre de remplacer par un 0 toutes les espaces présentes dans la chaîne spécifiée, et d’enregistrer le résultat dans la variable nommée « résultat1 ». Le deuxième appel de fonction doit quant à lui permettre de limiter le nombre d’espaces à l’aide du quatrième paramètre de transfert (facultatif). Ici, il est donc chargé de remplacer les deux premières espaces de la chaîne spécifiée par un 0 et d’enregistrer le résultat dans la variable appelée « résultat2 ».

Le résultat du code ci-dessus se présente alors de la manière suivante :

'python0estt0un0excellent0langagedeprogrammation'
'python0est0un excellent langage de programmation'

re.split()

Comme son nom l’indique, la fonction split() du module « re » rappelle le fonctionnement de la fonction split() intégrée à Python. Elle permet elle aussi de décomposer une chaîne de caractères en une liste. La chaîne de caractères est donc interrompue à chacune de ses correspondances avec une expression régulière. Sans surprise, cette fonction requiert donc un modèle de recherche en tant que premier paramètre, ainsi que la chaîne de caractères à fractionner en tant que deuxième paramètre. Pour limiter le nombre de fractionnements de votre chaîne, vous pouvez ajouter un nombre en tant que troisième paramètre (facultatif). Celui-ci vous permet de spécifier le nombre maximal de fractionnements de votre chaîne. Laissez-nous vous présenter un autre exemple pour vous aider :

import re
string = "python est un excellent langage de programmation"
regex = "\s"
résultat1 = re.split(regex, string)
print(résultat1)
résultat2 = re.split(regex, string, 1)
print(résultat2)
Python

Le code de l’exemple précédent doit, en majeure partie, déjà vous être familier ; seul l’appel de la fonction split() a changé. La fonction split() est d’abord appelée au niveau de la chaîne de caractères ; elle a pour mission de la fractionner chaque fois qu’une espace apparaît. La liste qui en résulte est ensuite affectée à la variable « résultat1 ». Le deuxième appel de split() limite à 1 le nombre de fractionnements, grâce au troisième paramètre facultatif. Il affecte ensuite ce résultat à la variable « résultat2 ». Le programme ainsi exécuté donne le résultat qui suit :

['python', 'est', 'un', 'excellent', 'langage', 'de', 'programmation']
['python', 'est un excellent langage de programmation']

re.search()

La fonction search(), comme son nom l’indique, permet de rechercher une correspondance au sein d’une chaîne de caractères. Pour ce faire, elle utilise l’expression régulière en tant que premier paramètre et la chaîne à rechercher en tant que deuxième paramètre. Elle renvoie un Python Match Object (soit un objet de correspondance), qui porte toujours sur la première correspondance trouvée. Si aucune correspondance n’est trouvée, la fonction renvoie alors la valeur « None ». Pour mieux comprendre la marche à suivre avec cette fonction, vous pouvez vous référer à l’exemple ci-dessous :

import re
string = "python est un excellent langage de programmation"
regex = "\s"
match = re.search(regex, string)
if match:
	print("RegEx a été trouvée.")
else:
	print("RegEx n’a pas été trouvée.")
Python

La fonction search() est appelée avec une expression régulière permettant de rechercher les espaces, ainsi qu’avec une chaîne de caractères. L’objet de correspondance renvoyé par l’appel de cette fonction atterrit dans la variable nommée « match ». L’instruction if…else de Python, que vous trouverez ci-dessous, peut servir à illustrer la situation : si une correspondance est trouvée, l’objet de correspondance n’est pas vide et le chemin if est sélectionné. Sans surprise, le résultat renvoyé par le programme est alors le suivant :

'RegEx a été trouvée.'

L’objet de correspondance

L’objet de correspondance est renvoyé par un appel de search(). Il contient des informations sur les occurrences identifiées par le modèle de recherche. Différentes fonctions vous permettent d’accéder à ces informations :

  • La fonction object.start() renvoie l’index du premier caractère de la sous-chaîne Python correspondant à votre modèle de recherche.
  • La fonction object.end() renvoie l’index du dernier caractère, par analogie avec la fonction start().
  • La fonction object.span() combine les fonctions start() et end() : elle renvoie un tuplet en Python contenant le premier et le dernier index de la sous-chaîne concernée.
  • La fonction object.string renvoie la chaîne de caractères analysée par vos soins.
  • La fonction object.re renvoie la Python RegEx spécifiée pour la fonction search().

Pour illustrer toutes ces fonctions, laissez-nous compléter le dernier de code par les appels de fonction correspondants :

import re
string = "python est un excellent langage de programmation"
regex = "\s"
match = re.search(regex, string)
if match:
	print("RegEx a été trouvée.")
else:
	print("RegEx n’a pas été trouvée.")
print(match.start())
print(match.end())
print(match.span())
print(match.string)
print(match.re())
Python

Le résultat du programme se présente alors de la manière suivante :

'RegEx a été trouvée.'
6
7
(6, 7)
'python est un excellent langage de programmation'
re.compile(’\\s’)

En premier lieu, la chaîne « RegEx a été trouvée. » est présente, car l’objet de correspondance n’est pas vide et la condition if s’applique en conséquence. Ensuite, l’index de la première correspondance est affiché. Comme la première espace correspond à l’index « 6 », cette valeur n’est en rien surprenante. Il en va de même pour la valeur « 7 », affichée suite à l’appel de la fonction end(). Le n-uplet « (6, 7) » combine l’appel des fonctions start() et end(), avec les deux index indiqués en une seule fois. La chaîne de caractères renvoyée par l’objet de correspondance en tant que résultat est elle aussi sans surprise.

Mais alors, qu’en est-il du résultat « re.compile(’\s’) » ? Il s’agit d’un objet lié aux Python RegEx. Celui-ci est créé si la chaîne de caractères renseignée en tant qu’expression régulière est traitée comme telle. Comme vous pouvez le voir, vous pouvez passer par votre objet de correspondance pour afficher l’objet lié aux RegEx.