Salut à vous,
J'ai lu je ne sais plus où le terme compiler une regex. J'ai un vague souvenir qu'on l'utilise comme ceci, mais qqn pourrait donner un exemple concret ?
Merci ;)
Code:
1
2
3
4
5 $a = "aaa"; $b = "bbb"; @global =~ qr{s/$a/$b/}
Version imprimable
Salut à vous,
J'ai lu je ne sais plus où le terme compiler une regex. J'ai un vague souvenir qu'on l'utilise comme ceci, mais qqn pourrait donner un exemple concret ?
Merci ;)
Code:
1
2
3
4
5 $a = "aaa"; $b = "bbb"; @global =~ qr{s/$a/$b/}
heu peux tu préciser ce que tu souhaites faire
En fait je souhaite comprendre ce que cela veut dire par le biais d'une démonstration.
Pour commencer, ton exemple est absurde (soit dit sans vouloir être blessant) : on n'utilise pas qr comme ça. Ça marche, certes, et aussi bien qu'autre chose, mais ça ne sert à rien de mettre qr là. qr sert principalement à créer un objet regex, c'est à dire une variable contenant une regex. C'est très pratique pour tout un tas de choses, notemment pour composer des regex à partir d'autres regex, ou d'autres variables. C'est plus pratique que l'interpolation de variables dans pas mal de situations, et bien utilisé ça permet certaines optimisations. Je vais essayer de trouver de la doc en ligne, mais c'est pas simple. Je vais potasser mon Friedl à ce sujet pour trouver des exemples (ça ne me fera pas de mal, je ne suis pas sûr de me servir de qr autant que je pourrais).
EDIT : en fait, ça ne marche même pas, ton exemple, au temps pour moi.
Ce qu'on peut compiler, c'est une regex, pas une substitution ou un match, une regex, autrement dit :
remplace tous les "hello" par des "bye".Code:
1
2
3
4
5
6 my $regex = qr/hello/; while( <> ) { s/$regex/bye/; print; }
A noter que cet exemple n'a absolument aucun intérêt puisque :
fait exactement la même chose ( "hello" étant une chaîne constante, la regex n'est compilée qu'une fois, puis réutilisée à chaque ligne).Code:
1
2
3
4 while( <> ) { s/hello/bye/; print; }
Dans le cas suivant compiler la regex a plus de sens :
En effet, perl (l'interpréteur) ne peut pas deviner que $variable ne changera pas d'une itération de la boucle à l'autre, la regex sera donc recompilée à chaque itération, avec une pénalité en temps d'exécution (probablement négligeable ici, mais pas dans tous les cas)...Code:
1
2
3
4
5
6 my $variable = <STDIN>; while( <> ) { s/$variable/bye/g; print; }
C'est une bonne idée d'utiliser alors :
Dans ce cas la regex ne sera compilée qu'une seule fois.Code:
1
2
3
4
5
6
7 my $variable = <STDIN>; my $regex = qr/$variable/; while( <> ) { s/$regex/bye/g; print; }
L'autre intérêt de qr// c'est de nommer des parties de regex, de façon à construire des regexs complexes de façon plus maintenable, ainsi que de faciliter le passage de regex en paramètre d'une fonction, ou en sortie d'une fonction :
--Code:
1
2
3
4
5
6
7
8
9
10
11
12 my @days = qw/Lundi Mardi Mercredi Jeudi Vendredi Samedi Dimanche/; my $rday = list2regex( @days ); my @months = qw/.../; my $rmonth = list2regex( @months ); # $1 : jour, $2 : jour du mois, $3 : mois, $4 : année my $rdate = qr{($rday) (\d+) ($rmonth) (\d+)}; sub list2regex { my $temp = join '|', map {quotemeta} @_; return qr/(?:$temp)/; }
Jedaï
Merci bcp, j'y vois plus clair maintenant.
Ca doit être ce type d'info qui a du m'interloquer : "faciliter le passage de regex en paramètre d'une fonction"
Plus exactement, Perl vérifie si le contenu de la variable a changé avant de recompiler, donc il ne recompile pas à chaque fois. Mais en effet, le coût de cette vérification étant non nul, on y gagne.Citation:
Envoyé par Jedai
À noter en passant que, quand on crée un objet regex dans le but de l'envoyer à une fonction ou composer une regex plus complexe, il faut être très prudent avec les parenthèses capturante. Je pense que tout le monde sera d'accord pour dire que mettre des parenthèses capturantes dans un objet regex est, d'une façon générale, à éviter. À moins, bien sûr, d'avoir une raison très précise de le faire (de même qu'on peut hypothétiquement avoir une raison très précise de se planter un clou dans la rotule, par exemple).Citation:
L'autre intérêt de qr// c'est de nommer des parties de regex, de façon à construire des regexs complexes de façon plus maintenable, ainsi que de faciliter le passage de regex en paramètre d'une fonction, ou en sortie d'une fonction :
Code:
1
2
3
4
5
6
7
8
9
10
11
12 my @days = qw/Lundi Mardi Mercredi Jeudi Vendredi Samedi Dimanche/; my $rday = list2regex( @days ); my @months = qw/.../; my $rmonth = list2regex( @months ); # $1 : jour, $2 : jour du mois, $3 : mois, $4 : année my $rdate = qr{($rday) (\d+) ($rmonth) (\d+)}; sub list2regex { my $temp = join '|', map {quotemeta} @_; return qr/(?:$temp)/; }