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

s///g

8 réponses
Avatar
kurtz le pirate
bonjour,

je ne dois pas être bien réveillé ce matin :((

for (@file) {
print "1>$_\n";
#s/(<.*>)/$points{$1}/g;
s/(<.+>)/XXX/g;
print "2>$_\n\n";
}


la substitution ne se fait que pour la première occurence et pas pour
les autres. ce script retourne par exemple :

1>cylinder{<0, 0, 1.0705>,<0.71364, 0, 0.79788> R2}
2>cylinder{XXX R2}


pourtant il y a bien de 'g' :(( j'ai raté quoi ?


--
klp

8 réponses

Avatar
Vincent Lefevre
Dans l'article ,
kurtz le pirate écrit:

for (@file) {
print "1>$_n";
#s/(<.*>)/$points{$1}/g;
s/(<.+>)/XXX/g;
print "2>$_nn";
}

la substitution ne se fait que pour la première occurence et pas pour
les autres. ce script retourne par exemple :

1>cylinder{<0, 0, 1.0705>,<0.71364, 0, 0.79788> R2}
2>cylinder{XXX R2}


<.*> matche <0, 0, 1.0705>,<0.71364, 0, 0.79788>

pourtant il y a bien de 'g' :(( j'ai raté quoi ?


Peut-être la différence entre greedy et non-greedy. Essaie (<.*?>)
ou bien (<[^>]*>).

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Avatar
Klaus
On May 12, 12:59 pm, Vincent Lefevre <vincent+ wrote:
Dans l'article ,
kurtz le pirate écrit:

for (@file) {
print "1>$_n";
#s/(<.*>)/$points{$1}/g;
s/(<.+>)/XXX/g;
print "2>$_nn";
}
la substitution ne se fait que pour la première occurence et pas pour
les autres. ce script retourne par exemple :
1>cylinder{<0, 0, 1.0705>,<0.71364, 0, 0.79788> R2}
2>cylinder{XXX R2}


<.*> matche <0, 0, 1.0705>,<0.71364, 0, 0.79788>

pourtant il y a bien de 'g' :(( j'ai raté quoi ?


Peut-être la différence entre greedy et non-greedy. Essaie (<.*?>)


Tout à fait.

Pour des explications sur les quantificateurs "gourmands" ("greedy" en
Anglais), comme par ex. /.*/, contre les quantificateurs "minimaux" ou
"sobres" ("non-greedy" en Anglais), comme, par ex. /.*?/, voir
http://perl.enstimac.fr/DocFr/perlretut.html paragraphe
"Reconnaissances répétées".

ou bien (<[^>]*>).


Egalement correct. TIMTOWDI oblige.

Pour des explications sur cette technique, voir le livre "Perl best
practices" de Damian Conway, chapitre 12 "Regular Expressions",
paragraphe "Unconstrained Repetitions".

--
Klaus


Avatar
kurtz le pirate
In article ,
kurtz le pirate wrote:

bonjour,

je ne dois pas être bien réveillé ce matin :((

for (@file) {
print "1>$_n";
#s/(<.*>)/$points{$1}/g;
s/(<.+>)/XXX/g;
print "2>$_nn";
}


mais oui bien sûr, les regex sont gourmandes. merci bien à tout les deux.
j'avais aussi, entre temps, trouvé.

mais j'ai toujours le même type de problème dans une autre boucle. celle
ou j'essaye justement d'isoler les <.$?> :

$indice=0;
for (@file) {
chomp;
if (/(<.*?>)/) {
if (!exists($points{$1})) {
$points{$1}= "points[$indice]";
$indice++;
}
}
}

ne détecte pas le troisième <..> dans une ligne comme ça :

triangle{<0.35682, -0.61803, -0.79788>,<-0.13629, -1.,
-0.35682>,<-0.2582, -0.44721, -0.67597>}


--
klp

Avatar
Klaus
On May 12, 4:50 pm, kurtz le pirate wrote:
mais j'ai toujours le même type de problème dans une autre boucle. ce lle
ou j'essaye justement d'isoler les <.$?> :

$indice=0;
for (@file) {
chomp;
if (/(<.*?>)/) {


# il faut remplacer le "if (/.../)" par un "for (/.../g)":

for (/(<.*?>)/g) {

if (!exists($points{$1})) {
$points{$1}= "points[$indice]";


# En conséquence, remplacer le "$1" par "$_":

if (!exists($points{$_})) {
$points{$_}= "points[$indice]";

$indice++;
}
}
}

ne détecte pas le troisième <..> dans une ligne comme ça :

triangle{<0.35682, -0.61803, -0.79788>,<-0.13629, -1.,
-0.35682>,<-0.2582, -0.44721, -0.67597>}


--
Klaus

Avatar
Vincent Lefevre
Dans l'article ,
kurtz le pirate écrit:

mais j'ai toujours le même type de problème dans une autre boucle. celle
ou j'essaye justement d'isoler les <.$?> :

$indice=0;
for (@file) {
chomp;
if (/(<.*?>)/) {
if (!exists($points{$1})) {
$points{$1}= "points[$indice]";
$indice++;
}
}
}

ne détecte pas le troisième <..> dans une ligne comme ça :

triangle{<0.35682, -0.61803, -0.79788>,<-0.13629, -1.,
-0.35682>,<-0.2582, -0.44721, -0.67597>}


@file contient chaque ligne du fichier? Si c'est le cas, c'est normal
qu'il ne trouve pas le <...> coupé en deux. Il faut mettre tout le
contenu du fichier dans une seule variable avec un truc du style

$file = do { local $/; <FILE> };

et utiliser les modifieurs s (pour que . matche le n) et g (recherche
globale, voir les pages man pour ses diverses utilisations possibles).

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Avatar
kurtz le pirate
nickel ! un grand merci à vous deux. maintenant fini, voilà le morceau
principal du code :

open (SOURCE,"<",$source) or die "Error openning $source : $!!n";
@file=<SOURCE>;
close (SOURCE);
chomp(@file);


my $indice=0;
for (@file) {
for (/(<.*?>)/g) {
if (!exists($points{$_})) {
$points{$_}= "$indice";
$indice++;
}
}
}


my $nbPoints = keys %points;
print "#declare points = array[$nbPoints];n";
for (sort sortHashByValueNumeric(keys %points)) {
print "#declare points[$points{$_}] = $_;n";
}
print "n";


for (@file) {
s/(<.*?>)/points[$points{$1}]/g;
print "$_n";
}


a+
--
klp
Avatar
espie
In article ,
kurtz le pirate wrote:

nickel ! un grand merci à vous deux. maintenant fini, voilà le morceau
principal du code :

open (SOURCE,"<",$source) or die "Error openning $source : $!!n";
@file=<SOURCE>;
close (SOURCE);
chomp(@file);


Juste un truc, evite les filehandle a la SOURCE, ca ne cause que des
emmerdes plus tard.

open (my $fh,"<",$source) or die "Error openning $source : $!!n";
@file=<$fh>;
close ($fh);
chomp(@file);

presente quelques avantages. L'un d'eux, et pas le moindre, etant que $fh
est facile a passer en parametre a une fonction.

Avatar
Klaus
On May 13, 9:44 am, (Marc Espie) wrote:
In article ,
kurtz le pirate wrote:
open (SOURCE,"<",$source) or die "Error openning $source : $!!n";


open (my $fh,"<",$source) or die "Error openning $source : $!!n";

presente quelques avantages. L'un d'eux, et pas le moindre, etant que $fh
est facile a passer en parametre a une fonction.


correct.

Voir http://perl.enstimac.fr/DocFr/perlopentut.html
paragraphe "Handles de fichier indirects".

--
Klaus