Comment trouver la plus petite séquence correspondante avec une RegEx

Par défaut, les expressions régulières sont dites « gloutonnes », c’est-à-dire qu’elles vont capturer le plus de caractères possible. Il existe toutefois une façon d’inverser cela. 😋

5 minutes de lecture
Comment trouver la plus petite séquence correspondante avec une RegEx
Photo par Pixabay sur Pexels.

Contexte

Les expressions régulières, communément appelées RegEx (mot-valise formé depuis l'anglais regular expression), peuvent être des fonctionnalités très puissantes dans la plupart des langages informatiques. Pour en retirer le plus de bénéfices possible, il faut néanmoins être familier avec leur syntaxe de base et celle plus avancée.

Afin de me remémorer une de ces fonctions avancées pour mon moi futur, j'ai décidé de vous écrire un petit article sur les quantificateurs non gloutons.

Toutefois, avant de rentrer dans le vif du sujet, je souhaite expliquer le dernier problème que j'ai résolu à l'aide des quantificateurs non gloutons.

Problème

Afin d'extraire et de visualiser certaines informations se trouvant dans une structure HTML complexe (des tables dans des tables), je souhaitais nettoyer partiellement le HTML suivant :

<table>
  <tr><td title="Attributs" style="width: 40px;"><div></div></td><td><div>Attributs</div></td><td><div></div></td></tr><tr><td colspan="3"><table><tr><td layernode style="width: 52px;"><div></div></td><td><div>Photos</div></td><td><div></div></td></tr><tr><td colspan="3"><table><tr><td style="width: 64px;"><div></div></td><td><div>Certificat de nationnalité</div></td><td><div></div></td></tr><tr><td colspan="3"><table><tr><td><div id="tb31" style="font-size: 36px;"><table style="font-size: 12px"><tr style="border: 1px solid"><td style=""><img style="overflow:auto;margin:auto;top:0;left:0;bottom:0;right:0" src="data:image/png;XXXXX">[...]
Extrait du code HTML problématique.

Cette structure avait beaucoup d'attributs ou de balises qui m'empêchaient de comprendre et d'extraire les informations que je recherchais. J'aurais pu retirer complètement toute balise HTML à l'aide d'un outil spécialisé, mais j'aurais perdu certaines informations visuelles comme les images ou le style... 😣

Je me suis donc résolu à supprimer les attributs qui ne m'apportaient pas nouvelles informations, comme l'attribut title ci-dessous.

Hum, mon expression régulière a capturé beaucoup plus que je ne le pensais... 🤔

Heureusement pour moi, je me souvenais qu'il y avait une façon de faire afin d'avoir des matches plus courts. Après quelques recherches, j'ai enfin pu trouver le nom de cette fonctionnalité : lazy. 😴

Solution

Par défaut, de par leur fonctionnement, les expressions tentent de capturer le plus de caractères possible. Ce comportement a un nom : greedy en anglais, que l'on peut traduire en français par gourmand ou glouton.

Or, dans des cas comme celui plus haut, trop de caractères sont ainsi capturés, rendant l'utilisation d'une expression régulière inutile. 😶

Heureusement, il est possible d'inverser ce comportement, de façon à capturer le moins de caractères possible. Ce contraire est connu sous le terme lazy ou de non-greedy en anglais, que l'on peut traduire en paresseux ou non-glouton en français.

Comment faire? Il suffit de rajouter un point d'interrogation après le quantificateur, pour avoir *? ou +? par exemple.

Voici la même expression régulière utilisée précédemment, mais en mode « lazy » :

La version lazy de la même expression régulière précédente.

Une importante différence, n'est-ce pas? 🤗

Dans le cas de mon problème, la RegEx suivante m'a permis de retirer tous les attributs qui ne m'intéressaient pas.

 (?:aria-.*?|id|title|alt|class|legendsdivid|data-dojo-attach-point|role|tabindex|layertrnodeid|layercontenttrnodeid|widgetid|subnodeid|imageshowlegenddivid)=".*?"

Et maintenant, en bonus, de quelle façon pourriez-vous retirer toutes les balises HTML du code suivant? 🤔

<b>Hello world!</b>

Et oui, tout simplement avec l'expression régulière <.*?>! 😊

Simple, non? 🤭

Conclusion

Maintenant que vous connaissez les lazy RegEx, vos expressions régulières seront encore plus puissantes que jamais! 🐱‍👤

Et n'oubliez pas, si jamais vous rencontrez une expression régulière avec des parties que vous ne connaissez pas, vous pouvez utiliser le site de RegExr, qui vous permettra de tester et d'expliquer vos expressions régulières! 🤓

RegExr: Learn, Build, & Test RegEx
RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).

À la prochaine! 🥰

Divers

Tableau

Selon cet article sur les quantificateurs dans les expressions régulières en .NET, il serait également possible de rendre d'autres quantificateurs « lazy ».

Quantificateur greedy Quantificateur lazy Description
* *? Correspond zéro ou plusieurs fois.
+ +? Correspond une ou plusieurs fois.
? ?? Correspond zéro ou une fois.
{ n } { n }? Correspond exactement n fois.
{ n ,} { n ,}? Correspond au moins n fois.
{ n , m } { n , m }? Correspond entre n et m fois.

Toutefois, je ne suis actuellement pas en mesure de me prononcer sur ces cas, car je n'ai pas encore rencontré de cas nécessitant une telle mesure. Peut-être qu'un lecteur de cet article pourra nous renseigner sur le sujet? 🤔

Références

Si vous souhaitez en apprendre davantage sur le sujet, voici quelques articles ci-dessous qui pourraient vous intéresser. 😉

Quantificateurs gloutons ou paresseux
Quantifiers in Regular Expressions
Learn about regular expression quantifiers, which specify how many instances of a character, group, or character class must be present in the input to match.
What do ‘lazy’ and ‘greedy’ mean in the context of regular expressions?
What are these two terms in an understandable way?