4.1. Expressions régulières

4.1.1. Introduction

Les expressions régulières (ou rationnelles), communément abrégé en regex, constituent un outil fondamental lorsqu’il s’agit de rechercher/remplacer des caractères d’une manière complexe.

Les regex elles-mêmes demanderaient un livre entier pour être maitrisé, aussi conseillerai-je de se reporter à des livres ou des sites spécialisés sur le sujet, même si je donnerai les bases pour s’en servir et comprendre leur intérêt.

Une expression régulière consiste en une chaine de caractères, souvent appelée “motif” [1]. Elle sera donc écrite entre guillemets. Un r placé devant la chaine permet de considérer l’antislash \ comme un caractère normal. Par exemple, on pourra écrire :

>>> regex = r'a0\n'
>>> regex
'a0\\n'

Note

OpenOffice permet de faire des recherches par regex (Rechercher ‣ Autres options). Cela peut être utile pour s’entrainer à manipuler les regex.

Footnotes

[1]Ou encore “pattern” en anglais.

4.1.2. Syntaxe

Les regex répondent à une syntaxe très codifiée et possèdent de nombreux symboles ayant un sens particulier.

Pour débuter, tout caractère alphanumérique n’a pas de signification spéciale : A correspond simplement à la lettre A, 1 au chiffre 1, etc.

Quant aux principaux symboles spéciaux, il sont :

  • . : désigne n’importe quel caractère ;
  • ^ : indique que le début de la chaine doit correspondre (c’est à dire qu’une chaine ne pourra correspondre que si elle commence de la même manière, qu’elle est précédée d’espaces ou d’un saut de ligne) ;
  • $ : indique que la fin de la chaine doit correspondre (la même remarque que précédemment s’applique, mais au niveau de la fin) ;
  • {n} : indique que le caractère précédent doit être répété n fois.
  • {n,m} : indique que le caractère précédent doit être répété entre n et m fois.
  • * : le caractère précédent peut être répété aucune ou plusieurs fois. Par exemple, à ab* peuvent correspondre : a, ab, ou a suivi d’un nombre quelconque de b.
  • + : le caractère précédent peut être répété une ou plusieurs fois. Par exemple, à ab+ correspond un a suivi d’un nombre quelconque de b.
  • ? : le caractère précédent peut être répété zéro ou une fois. Par exemple, à ab? correspondent ab et a.

Les quatres derniers symboles sont dits “gourmands” [2] : cela signifie qu’ils chercheront un maximum de caractères, ce qui peut parfois poser problème. Pour éviter ce comportement, on peut rajouter un ? après ces derniers, c’est à dire utiliser : ??, +? et *?.

L’antislash permet d’échapper tous ces caractères spéciaux.

Les crochets [] permettent d’indiquer une plage de caractère, par exemple [e-h] correspondra à e, f, g ou h. Les parenthèses permettent de grouper certaines expressions [3].

Finalement, il reste quelques caractères spéciaux assez utiles :

  • \w : il correspond à tout caractère alphabétique, c’est à dire qu’il est équivalent à [a-zA-Z] ;
  • \W : il correspond à tout ce qui n’est pas un caractère alphabétique ;
  • \d : il correspond à tout caractère numérique, c’est à dire qu’il est équivalent à [0-9] ;
  • \D : il correspond à tout ce qui n’est pas un caractère numérique.

Footnotes

[2]“Greedy” en anglais.
[3]Ce qui peut permettre de s’y référer par la suite.

4.1.3. Utilisation

Le module s’appelle re.

Il existe deux manières d’utiliser les regex :

  1. La première consiste à appeler la fonction avec en premier paramètre le motif, et en deuxième paramètre la chaine à analyser.
  2. La seconde consiste à compiler la regex, et à ensuite utiliser les méthodes de l’objet créer pour analyser une chaine passée en argument. Cette méthode permet d’accélérer le traitement lorsqu’une regex est utilisée plusieurs fois.

La plupart des fonctions et méthodes prennent des arguments optionnels, appelés drapeau (“flag” en anglais) qui permettent de modifier le traitement de l’objet. Le drapeau le plus intéressant est re.I (ou re.IGNORECASE) qui permet d’ignorer la casse lors de la recherche.

re.compile(pattern)

Compiler une expression régulière et retourne un objet contenant les mêmes méthodes que les fonctions décrites juste après.

re.search(pattern, string)

Cherche le motif dans la chaine passée en argument et retourne un MatchObject si des correspondances sont trouvées, sinon retourne None.

re.split(pattern, string)

Découpe la chaine string selon les occurences du motif.

>>> re.split(r'\W', 'Truth is beautiful, without doubt.')
['Truth', 'is', 'beautiful', '', 'without', 'doubt', '']
re.findall(pattern, string)

Retourne toutes les sous-chaines de string correspondant au motif.

re.sub(pattern, repl, string)

Retourne la chaine string où le motif a été remplacé par repl.

Le principal intérêt est d’utiliser la fonction match() afin de vérifier si une chaine se trouve dans une autre ou si elle respecte un certain format (ce qui peut être utilisé pour vérifier si un numéro de téléphone ou une adresse email à un format correct).

Pour tout autre utilisation des MatchObject, je renvoie le lecteur à la documentation.

La séquence

prog = re.compile(pattern)
result = prog.match(string)

est équivalente à

result = re.match(pattern, string)

4.1.4. Exemples

>>> import re
>>> # trouver tous les adverbes en -ment
>>> text = "Il s'était prudemment déguisé mais fut rapidement capturé par la police."
>>> re.findall(r"\w+ment", text)
['prudemment', 'rapidement']

4.1.5. Liens

4.1.6. Exercices

  1. Écrire un motif pour les numéros de téléphone, en prenant garde aux différentes manières de les écrire (avec un point, un tiret ou un espace entre les chiffres). On se limitera à des numéros français dont les numéros sont groupés par deux ou pas du tout.
  2. Utiliser le motif précédent qui extrait tous les numéros de téléphone d’un texte et qui les affiche à l’écran, sous une forme normalisée (par exemple tous les chiffres sont groupés par deux, et le séparacteur est un point).

Table des matières

Sujet précédent

4. Aspects spécifiques

Sujet suivant

4.2. Gestion des fichiers et dossiers

Cette page