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">[...]
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.

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 » :

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! 🤓

À 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. 😉


