Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

pb de debutant avec les susbtitutions

3 réponses
Avatar
Alain Adelmar
Bonjour tout le monde
J'ai un probléme pour substituer une variable reconnu dans une boucle
foreach
pouvez vous d'indiquer mon/mes erreurs
ou un autre moyen d'y arriver?
merci.
alain
_________
#!/usr/bin/perl
# remd: essai light sur la recherche de n motif et sa substitution, sur
la mm ligne.


# dans un fichier ayant des lignes de ce type
my $ligne_type ='<a href="C:\pub\XWindow-User-HOWTO-VF.html">Retour</a>|
<a href="mon_modele.html#dico_top">Suivant</a>| <a
href="index.html#100">Sommaire</a>';

# j'arrive a isoler des modéles comme
my $mot = "href=\"(.*?)\"\>";
# meme plusieurs dans la meme ligne avec
my @ls_m = ($ligne_type =~ /$mot/ig);

# seulement une fois mes modéles modifiés par plusieurs controles sur un
foreach (@ls_m) style
foreach $m (@ls_m) {
$lnkbrut = $m;
$oldlb = $lnkbrut;
print "oldlb vaut $oldlb\n";
$toto = "toto";
$i++;
($lnknet, $encre) = split(/\#/, $lnkbrut);
# je verifie
print "lnknet est egal a $lnknet\nencre est egale a $encre\n";
($rootlnknet, $ext) = split(/\./, $lnknet);
#idem
print "rootlnknet est egal a $rootlnknet\nextention est egale a $ext\n";
print "le $i eme mot est $m\n";

my $ligne_type =~ s/()$oldlb()/$1$toto$2/isg;
print "ligne_type vaut maintenant $ligne_type\n";
# ou
$nwline =(my $ligne_type =~ s/()$oldlb()/$1$toto$2/isg);
print "nwline vaut maintenant $nwline\n";
#SCONTROL:if ($lnknet =~ /[\/]|[\\]|[\.]/) {
# &degage_path;
}

#Pourquoi je peut pas substituer?
#quel est la valeur non initialisé qu'il ne comprend pas ?
# pourquoi ca marche pour un seul motif et pas pour plusieurs?

3 réponses

Avatar
Jean-Baptiste Mazon
Alain Adelmar writes:

Bonjour tout le monde
J'ai un probléme pour substituer une variable reconnu dans une boucle
foreach
pouvez vous d'indiquer mon/mes erreurs
ou un autre moyen d'y arriver?
merci.


L'erreur fondamentale me semble être l'absence du bloc suivant en tête
de fichier:

use strict;
use warnings;

En activant ne serait-ce que warnings, perl nous dit tout seul (par
chance, mais ça suffira pour notre cas) ce qui ne va pas:

"my" variable $ligne_type masks earlier declaration in same scope at subst.pl line 33.
30> my $ligne_type =~ s/()$oldlb()/$1$toto$2/isg;
33> $nwline =(my $ligne_type =~ s/()$oldlb()/$1$toto$2/isg);

Telle quelle, ces lignes ne sont pas de simples substitution, ce sont
d'abord des déclarations de variables. Mais la valeur initiale d'une
variable, c'est undef, et c'est à cet undef que la substitution va
s'appliquer. D'ailleurs, ça n'échappe pas non plus à perl:

Use of uninitialized value in substitution (s///) at subst.pl line 30.
Use of uninitialized value in substitution (s///) at subst.pl line 33.

Il suffit d'ôter les mot-clé `my' de ces deux lignes pour que tout
rentre dans l'ordre. Enfin... pour en arriver à l'erreur suivante:

Can't find Unicode property definition "u" at subst.pl line 30.
30> $ligne_type =~ s/()$oldlb()/$1$toto$2/isg;

Maintenant, le problème est que notre regex est mal formée. Ça ne
saut pas aux yeux parce qu'elle est cachée dans la variable $oldlb.
La valeur de $oldlb à ce moment-ci nous a été donnée par le script
juste avant:

oldlb vaut C:pubXWindow-User-HOWTO-VF.html

Or en contexte regex, le caractère peut définir des métacaractères.
En l'occurrence, p a le fonctionnement suivant:

pP Reconnaît la propriété P (nommée). Utilisez p{Prop}
pour les noms longs

Source: http://perl.enstimac.fr/DocFr/perlre.html#expressions%20rationnelles

Ce n'est pas du tout ce qu'on veut (contrairement à la ligne [ my
@ls_m = ($ligne_type =~ /$mot/ig) ] du début). Ici, la variable
intégrée à la regex n'est pas une regex elle-même, mais une simple
chaine. Il faut informer perl de la traiter comme telle. C'est
expliqué quelques lignes plus haut dans la documentation vers laquelle
je viens de pointer.

Avec toutes ces corrections, j'en arrive au résultat final suivant:

ligne_type vaut maintenant <a href="toto">Retour</a>| <a href="toto">Suivant</a>| <a href="toto">Sommaire</a>




Résultat des courses
--------------------

1) use strict; use warnings;
Toujours. Toujours. Toujours.

2) Utiliser `my', c'est bien. D'ailleurs, strict ne laisse pas
vraiment le choix. Par contre, il faut savoir ce qu'il fait.

3) Attention à l'interpolation de variables dans les regex!
Une bonne convention de nommage peut aider à s'y retrouver, par
exemple en suffixant toutes les variables qui contiennent des regex
par _re.

Conseil: si c'est pour gérer du HTML et des URI, il existe déjà de
nombreux modules qui font ça très bien et même mieux en plus simple et
plus fiable.

Avatar
Alain Adelmar
Alain Adelmar writes:


Bonjour tout le monde
J'ai un probléme pour substituer une variable reconnu dans une boucle
foreach
pouvez vous d'indiquer mon/mes erreurs
ou un autre moyen d'y arriver?
merci.



L'erreur fondamentale me semble être l'absence du bloc suivant en tête
de fichier:

use strict;
use warnings;

En activant ne serait-ce que warnings, perl nous dit tout seul (par
chance, mais ça suffira pour notre cas) ce qui ne va pas:

"my" variable $ligne_type masks earlier declaration in same scope at subst.pl line 33.
30> my $ligne_type =~ s/()$oldlb()/$1$toto$2/isg;
33> $nwline =(my $ligne_type =~ s/()$oldlb()/$1$toto$2/isg);

Telle quelle, ces lignes ne sont pas de simples substitution, ce sont
d'abord des déclarations de variables. Mais la valeur initiale d'une
variable, c'est undef, et c'est à cet undef que la substitution va
s'appliquer. D'ailleurs, ça n'échappe pas non plus à perl:

Use of uninitialized value in substitution (s///) at subst.pl line 30.
Use of uninitialized value in substitution (s///) at subst.pl line 33.

Il suffit d'ôter les mot-clé `my' de ces deux lignes pour que tout
rentre dans l'ordre. Enfin... pour en arriver à l'erreur suivante:

Can't find Unicode property definition "u" at subst.pl line 30.
30> $ligne_type =~ s/()$oldlb()/$1$toto$2/isg;

Maintenant, le problème est que notre regex est mal formée. Ça ne
saut pas aux yeux parce qu'elle est cachée dans la variable $oldlb.
La valeur de $oldlb à ce moment-ci nous a été donnée par le script
juste avant:

oldlb vaut C:pubXWindow-User-HOWTO-VF.html

Or en contexte regex, le caractère peut définir des métacaractères.
En l'occurrence, p a le fonctionnement suivant:

pP Reconnaît la propriété P (nommée). Utilisez p{Prop}
pour les noms longs

Source: http://perl.enstimac.fr/DocFr/perlre.html#expressions%20rationnelles

Ce n'est pas du tout ce qu'on veut (contrairement à la ligne [ my
@ls_m = ($ligne_type =~ /$mot/ig) ] du début). Ici, la variable
intégrée à la regex n'est pas une regex elle-même, mais une simple
chaine. Il faut informer perl de la traiter comme telle. C'est
expliqué quelques lignes plus haut dans la documentation vers laquelle
je viens de pointer.

Avec toutes ces corrections, j'en arrive au résultat final suivant:

ligne_type vaut maintenant <a href="toto">Retour</a>| <a href="toto">Suivant</a>| <a href="toto">Sommaire</a>




Résultat des courses
--------------------

1) use strict; use warnings;
Toujours. Toujours. Toujours.

2) Utiliser `my', c'est bien. D'ailleurs, strict ne laisse pas
vraiment le choix. Par contre, il faut savoir ce qu'il fait.

3) Attention à l'interpolation de variables dans les regex!
Une bonne convention de nommage peut aider à s'y retrouver, par
exemple en suffixant toutes les variables qui contiennent des regex
par _re.

Conseil: si c'est pour gérer du HTML et des URI, il existe déjà de
nombreux modules qui font ça très bien et même mieux en plus simple et
plus fiable.


Waouuu, merci Jean-Baptiste

La limpidité de tes réponses m'a ouvert les yeux sur beaucoup de pb qui
me faisaient buter. J'ai tout compris, c'est geant.
Tu es vraiment doué pour expliquer les choses. Merci
Merci encore, je laisse le contenu de ta réponse en espérant qu'il serve
à d'autres débutants comme moi.

En ce qui concerne les modules, il va falloir que je m'y mette, que je
passe le pas.

Merci encore, tu m'as ouvert les yeux sur des choses essentielles.
alain


Avatar
Alain Adelmar
Alain Adelmar writes:


Bonjour tout le monde
J'ai un probléme pour substituer une variable reconnu dans une boucle
foreach
pouvez vous d'indiquer mon/mes erreurs
ou un autre moyen d'y arriver?
merci.



L'erreur fondamentale me semble être l'absence du bloc suivant en tête
de fichier:

use strict;
use warnings;

En activant ne serait-ce que warnings, perl nous dit tout seul (par
chance, mais ça suffira pour notre cas) ce qui ne va pas:

"my" variable $ligne_type masks earlier declaration in same scope at subst.pl line 33.
30> my $ligne_type =~ s/()$oldlb()/$1$toto$2/isg;
33> $nwline =(my $ligne_type =~ s/()$oldlb()/$1$toto$2/isg);

Telle quelle, ces lignes ne sont pas de simples substitution, ce sont
d'abord des déclarations de variables. Mais la valeur initiale d'une
variable, c'est undef, et c'est à cet undef que la substitution va
s'appliquer. D'ailleurs, ça n'échappe pas non plus à perl:

Use of uninitialized value in substitution (s///) at subst.pl line 30.
Use of uninitialized value in substitution (s///) at subst.pl line 33.

Il suffit d'ôter les mot-clé `my' de ces deux lignes pour que tout
rentre dans l'ordre. Enfin... pour en arriver à l'erreur suivante:

Can't find Unicode property definition "u" at subst.pl line 30.
30> $ligne_type =~ s/()$oldlb()/$1$toto$2/isg;

Maintenant, le problème est que notre regex est mal formée. Ça ne
saut pas aux yeux parce qu'elle est cachée dans la variable $oldlb.
La valeur de $oldlb à ce moment-ci nous a été donnée par le script
juste avant:

oldlb vaut C:pubXWindow-User-HOWTO-VF.html

Or en contexte regex, le caractère peut définir des métacaractères.
En l'occurrence, p a le fonctionnement suivant:

pP Reconnaît la propriété P (nommée). Utilisez p{Prop}
pour les noms longs

Source: http://perl.enstimac.fr/DocFr/perlre.html#expressions%20rationnelles

Ce n'est pas du tout ce qu'on veut (contrairement à la ligne [ my
@ls_m = ($ligne_type =~ /$mot/ig) ] du début). Ici, la variable
intégrée à la regex n'est pas une regex elle-même, mais une simple
chaine. Il faut informer perl de la traiter comme telle. C'est
expliqué quelques lignes plus haut dans la documentation vers laquelle
je viens de pointer.

Avec toutes ces corrections, j'en arrive au résultat final suivant:

ligne_type vaut maintenant <a href="toto">Retour</a>| <a href="toto">Suivant</a>| <a href="toto">Sommaire</a>




Résultat des courses
--------------------

1) use strict; use warnings;
Toujours. Toujours. Toujours.

2) Utiliser `my', c'est bien. D'ailleurs, strict ne laisse pas
vraiment le choix. Par contre, il faut savoir ce qu'il fait.

3) Attention à l'interpolation de variables dans les regex!
Une bonne convention de nommage peut aider à s'y retrouver, par
exemple en suffixant toutes les variables qui contiennent des regex
par _re.

Conseil: si c'est pour gérer du HTML et des URI, il existe déjà de
nombreux modules qui font ça très bien et même mieux en plus simple et
plus fiable.


Waouuu, merci Jean-Baptiste

La limpidité de tes réponses m'a ouvert les yeux sur beaucoup de pb qui
me faisaient buter. J'ai tout compris, c'est geant.
Tu es vraiment doué pour expliquer les choses. Merci
Merci encore, je laisse le contenu de ta réponse en espérant qu'il serve
à d'autres débutants comme moi.

En ce qui concerne les modules, il va falloir que je m'y mette, que je
passe le pas.

Merci encore, tu m'as ouvert les yeux sur des choses essentielles.
alain