Dans le monde de l’informatique, nous sommes souvent amenés à effectuer des tâches se rapportant au traitement de texte. Il existe un outil universel appelé regex, présentant souvent les solutions les plus performantes dans ce domaine. Les expressions régulières souffrent cependant d’une méconnaissance globale de leur fonctionnement, dû à leur apparence parfois… déroutante.
Qu’est-ce qu’une expression régulière ?
Une expression régulière, aussi plus communément appelée regex, est à première vue une simple chaîne de caractères. Ce qui la différencie ? Une syntaxe particulière qui, une fois interprétée, décrit alors un plus vaste ensemble de chaînes de caractères. On appelle cette chaîne descriptive un motif ou pattern en anglais.
Il ne s’agit pas d’un langage de programmation à proprement parler : la quasi-intégralité des langages disposent d’une bibliothèque regex permettant l’utilisation des expressions régulières. De plus, la syntaxe ne varie que très peu d’un langage à l’autre, ce qui facilite grandement la compatibilité entre les différentes plateformes, d’où le terme “universel” employé en introduction.
À quoi sert une expression régulière ?
Vous l’avez peut-être deviné : grâce aux regexes, nous pouvons isoler un certain type de texte et procéder à un traitement spécifique sur les échantillons prélevés.
Le cas le plus simple consiste à remplacer un mot par un autre dans un document. On peut aussi diminuer notre tolérance en autorisant certains écarts. Ci-dessous, un exemple :
Ce code repère les occurrences de l’expression « regex » et ses variantes dans le paragraphe et les remplace par « expression(s) régulière(s) ».
D’autres utilisations des regexes existent en cybersécurité : en général, lorsque vous créez un compte sur un nouveau site, celui-ci requiert un mot de passe respectant un certain nombre de règles. Pour vérifier si le mot de passe que vous insérez n’est pas en conflit avec le contrat, une regex est appliquée. De même, lorsqu’il s’agit de rentrer une adresse mail valide, il faut assurer la présence de l’arobase (pour ne citer qu’une contrainte) ; cela est relativement facile à retranscrire en termes de regexes.
Enfin, on retrouve les regexes en traitement automatique du langage naturel (NLP), en webscraping, en reconnaissance de motifs… Cette liste n’est pas du tout exhaustive, et vous serez très certainement amené à résoudre un problème de Data Science impliquant ces dernières !
Une apparence très controversée
Le dernier code peut mettre la puce à l’oreille : sans connaissance au préalable de l’architecture regex, difficile d’y comprendre grand chose… C’est cet aspect indigeste qui porte préjudice à cet outil pourtant loin d’être compliqué à maîtriser ! Il n’y a en effet qu’une poignée de lois régissant cette syntaxe, que nous allons essayer de débriefer.
Observons l’expression suivante :
[regex pour déterminer un pseudo valide (faire une image en couleur et en plusieurs parties)]
Pour déterminer le fonctionnement d’une regex, la première étape consiste à la décomposer en plusieurs sous-groupes. Cela tombe bien, le concept de groupe existe formellement : ils sont délimités par des parenthèses. Certaines parenthèses ne sont pas capturantes (comme celles associées à un lookahead) mais en règle générale, on compte chaque groupe par ordre d’ouverture de la parenthèse. Un groupe peut être capturant ou non en renseignant les caractères « ?: » en début de parenthèse. Pour être plus clair, un groupe capturant est un sous-ensemble du pattern global qui peut être isolé lors d’une recherche de motif.
- L’accent circonflexe « ^ » en début de liste est un caractère spécial ; il signifie que l’expression régulière ne capture que les occurrences en début de ligne. Inversement, le signe dollar $ assure que la fin de l’occurrence correspond à la fin d’une ligne.
- [A-ZÉ] : Lorsque des crochets sont présents, cela signifie qu’on accepte un (et un seul, s’il n’y a aucune indication ultérieure comme c’est le cas ici) caractère parmi l’ensemble fourni. A-Z correspond à « n’importe quelle lettre entre A majuscule et Z majuscule” (sensible à la casse !), auquel on ajoute la lettre É. Cette première partie du regex capte donc une lettre majuscule.
- (pattern)+ : le signe + permet de capturer pattern entre 1 et une infinité de fois.
- ((pattern1)|(pattern2)) : le symbole | signifie “nous capturons soit pattern1, soit pattern2”
- ( ([a-zéèà\- ])(?!\3{2}) ) : la première parenthèse fonctionne de la même manière que le premier groupe. On ne capture que les caractères présents dans le crochet ; de a à z minuscules, puis les accents, un espace, et le caractère spécial -. Pour appeler un caractère spécifique, il faut ajouter un back-slash \.
- La deuxième parenthèse est un lookahead négatif. Un lookahead, comme son nom l’indique, observe la suite de la chaîne de caractères et rajoute une condition pour que l’expression puisse être appliquée. Ici, cela se traduit par la condition “l’expression ([a-zéèà\- ]) capture du texte uniquement si elle n’est pas suivie par l’expression \3{2}”
- \3{2} : Lorsqu’on échappe un nombre (i.e lorsqu’un nombre est précédé du signe \), ce dernier fait référence au groupe associé. \3 correspond ainsi au troisième groupe du regex !
En revanche, si un nombre est contenu entre accolades, il indique le nombre exact d’occurrences du groupe précédent.
En d’autres termes, ce pattern signifie “capture un caractère parmi l’ensemble [a-zéèà\- ] sous réserve qu’il ne se répète pas plus de deux fois”. - (?<=\s)([A-ZÉ])(?![A-ZÉ]) : de même qu’avec un lookahead, le premier groupe de parenthèses est un lookbehind positif. \s capture tout espace blanc (un espace, une tabulation). En suivant la même logique, on devine que cette expression se traduit par la phrase “capture une lettre majuscule (A, B, …, Z, ou É) uniquement s’il est précédé d’un espace blanc et n’est PAS suivi par une autre lettre majuscule”.
- Finalement, (.+) signifie que l’on accepte n’importe quel caractère de manière illimitée.
Avec toutes ces règles en place, la totalité de ce regex devient soudainement très intuitive !
regex101 : une plateforme pour vérifier vos regexes
Pour vérifier le comportement d’une expression fraîchement créée, un site très pratique existe : https://regex101.com/
Avec cette interface, renseignez votre regex et le langage de programmation associés, puis inscrivez n’importe quelle chaîne de caractère dans l’espace dédié. Lorsque le pattern capture du texte, celui-ci sera surligné et relevé par le site.
Si la partie précédente vous a laissée perplexe, observez le texte qu’elle capture (ou non) :
Ce pattern ne prend que les pseudonymes valides selon une syntaxe définie.
Pour résumer
Les regexes sont à la fois simples d’utilisation et extrêmement versatiles ; maîtriser cet outil se révèle être un atout d’envergure. S’il est effectivement possible en général de résoudre un problème sans y avoir recours, la solution regex est très souvent la plus efficace de toutes.
Nous disposons d’une cheat sheet sur les regexes pour vous aider à pratiquer :
Cheat Sheet Regex
N’hésitez pas à consulter nos formations sur le NLP. Le NLP est un domaine fortement prolifique de l’IA défrayant les chroniques ; vous pouvez lire notre article sur le fonctionnement du très fameux ChatGPT pour vous en convaincre !