Dans Perl, les quantificateurs dans les expressions régulières — *, +, ?, {n,m} — sont par défaut avides (greedy) : ils capturent le maximum possible de caractères correspondant au modèle.
L'ajout de ? après le quantificateur le transforme en paresseux (lazy ou non-greedy) : il capture le minimum possible de caractères pour que l'ensemble de l'expression régulière corresponde.
my $str = 'foo <bar> baz <quux>'; $str =~ /<.*>/; # Capturera '<bar> baz <quux>'
my $str = 'foo <bar> baz <quux>'; $str =~ /<.*?>/; # Capturera '<bar>'
Une expression avide peut « manger » plus que prévu lors de l'analyse de HTML et d'autres constructions imbriquées !
Quelles sont les différences entre les deux expressions régulières lors de l'analyse de la chaîne
<a><b><c>:/<(.*)>/et/<(.*?)>/?
Réponse :
/<(.*)>/ (avide) capturera le maximum de bloc — correspondance : <a><b><c>/<(.*?)>/ (paresseuse) — seulement le premier groupe : <a>Exemple :
my $s = '<a><b><c>'; $s =~ /<(.*)>/; # $1: 'a><b><c' $s =~ /<(.*?)>/; # $1: 'a'
Histoire
Dans une application d'importation de titres d'actualités, le programmeur a voulu analyser le nom de la balise dans la chaîne
<title>Actualité</title>en utilisant/\<(.*)\>/. En conséquence, l'expression régulière capturait toute la chaîne entre le<premier et le>dernier, plutôt que l'élément souhaité. L'erreur a été remarquée lorsque des balises imbriquées sont apparues.
Histoire
Dans un analyseur logique pour extraire des chaînes citées, le modèle utilisé
/"(.*)"/capturait de manière inattendue tout entre la première et la dernière citation. Par conséquent, le balisage était cassé de manière incorrecte jusqu'à ce que le modèle soit remplacé par/"(.*?)"/.
Histoire
Dans un analyseur CSV automatique avec prise en charge des guillemets, le modèle a été mal écrit sur "avidité", ce qui a entraîné la fusion de plusieurs colonnes en une seule. L'échec de l'analyse a été identifié uniquement avec des données volumineuses — la modification paresseuse du modèle a résolu le problème.