Perl est l'un des langages où les expressions régulières sont intégrées à un niveau profond. L'opérateur principal de remplacement est s///, qui permet de rechercher et de remplacer des fragments de chaînes selon un modèle. Cette construction cache de nombreux aspects subtils, en particulier lors de l'utilisation de modèles gourmands/paresseux, du traitement multiligne et des options de remplacement.
L'opérateur s/// est présent dans Perl depuis les premières versions, et c'est Perl qui a posé les bases de la syntaxe des expressions régulières, plus tard empruntées par d'autres langages. La plupart des nuances de construction des modèles et des modificateurs (g, m, s, i, x, etc.) ont été introduites et développées précisément dans Perl.
Dans la pratique, de nombreux développeurs utilisent incorrectement les quantificateurs gourmands ou se mélangent dans les modificateurs (en particulier s et m), ce qui entraîne des résultats inattendus lors du remplacement dans des textes multiligne ou de grandes données. Des erreurs surviennent lors de l'attente d'une seule correspondance dans la chaîne, mais d'une autre, ou lors du remplacement uniquement des premières/dernières occurrences.
Il est important de choisir et de configurer correctement les modèles et de comprendre l'effet des modificateurs. Les modèles gourmands (par exemple, .*) capturent la plage maximale possible, tandis que les paresseux (par exemple, .*?) capturent la plage minimale requise.
Utilisation des modificateurs :
g — effectue le remplacement pour toutes les correspondancess — active le mode de traitement des chaînes multiligne, où le point (.) capture les nouveaux caractères de lignem — change le comportement des marqueurs ^ et $Exemple — remplacer les balises <tag> ... </tag> par un espace, un par un (paresseux) :
my $text = 'a <tag>1</tag> <tag>2</tag> b'; $text =~ s/<tag>.*?<\/tag>//g; print $text; # a b
Pour traiter des chaînes multiligne :
my $data = "Line 1 Line 2 <tag> DATA </tag> End"; $data =~ s/<tag>.*?<\/tag>//gs; print $data;
Caractéristiques clés :
s permet au point (.) de capturer des retours à la ligneg affecte le nombre de remplacements effectuésQue se passe-t-il si on ne met pas ? après le gourmand . lors du traitement de plusieurs balises ?*
Le quantificateur gourmand capturera la plage maximale possible, y compris les balises intermédiaires, ce qui entraînera la suppression inattendue de tout entre la première <tag> et la dernière </tag> :
my $txt = 'A <tag>1</tag> <tag>2</tag> B'; $txt =~ s/<tag>.*<\/tag>//g; print $txt; # A B
Ici, tout le morceau entre la première <tag> et la dernière </tag> a été remplacé.
Quelle est la différence entre le modificateur m et le modificateur s des expressions régulières Perl ?
s — le point (.) capture le caractère de nouvelle ligne ; m — change les ancres ^ et $ pour fonctionner à l'intérieur des lignes dans le texte multiligne. Leur utilisation est différente, mais on les confond souvent.
my $s = "abc def"; # /^def/ ne fonctionnera pas sans m print $s =~ /^def/m; # 1 (vrai)
Comment traiter toutes les occurrences d'un motif, si on applique s/// une seule fois ?
Sans le modificateur g, seule la première occurrence sera remplacée. Il faut ajouter g pour un remplacement global :
my $s = "foo bar foo"; $s =~ s/foo/baz/g; # remplacera les deux foo
Un développeur écrit un remplacement pour les balises HTML comme ceci :
$text =~ s/<tag>.*<\/tag>//g;
Résultat : tous les tags sont coupés avec le contenu entre eux — et non chacun séparément.
Avantages :
Inconvénients :
Utiliser un modèle paresseux et des modificateurs corrects :
$text =~ s/<tag>.*?<\/tag>//gs;
Avantages :
Inconvénients :