|
|
|
|
Bonjour,
Ca a l'air d'etre une question assez réccurentes, mais je n'ai pas réussi à trouver de solutions précise à mon probleme.
Voila, j'ai dans une variable une chaine de caractère de la forme suivante :
$var = "carac1=tatata carac2=tototo carac3=tititi carac4=tututu"
Et j'aurais 2 choses +/- similaire que je souhaiterais faire.
Premièrement :
extraire la carac2, c'est a dire tototo. Donc en fait, je cherche a prendre la chaine de caractère qui se trouve apres "carac2=" sachant que la longueur de la carac (tototo) n'est pas fixe et qu'elle n'est pas forcement suivi d'une autre carac.
Deuxiemement :
extraire les 4 premières lettres qui suive carac3= c'est a dire "titi".
Sachant que la chaine fera toujours au moins 4 lettres.
Merci d'avance pour vos solutions ou vos conseils.
Configuration: Windows XP Firefox 2.0.0.4
Super !
|
A quoi servent les parentheses autour des variables $un et $deux (bon, c'est sur qu'elles servent, parce que si je les mets pas ca me retourne 1) ?
$ echo Perl pour plaisir | perl -ne '$nombre = ($un,$deux,$trois) = $_ =~ /(p)/gi;print "$nombre\n"' $ echo Perl pour plaisir | perl -ne '$nombre = () = $_ =~ /(p)/gi;print "$nombre\n"' 3 $ echo Perl pour plaisir | perl -ne '$nombre = @nombre = $_ =~ /(p)/gi;print "$nombre\n"' 3 2. lire une liste dans un contexte de liste - retourne les éléments, avec la remarque que des valeurs sont perdu si on n'utilise pas le même nombre de variables - un solution c'est d'utiliser directement un tableau ou un hash (qui va bien dans ton cas vu que tu as des couple cle=valeur) $ echo Perl pour plaisir | perl -ne '($un) = $_ =~ /(p)/gi;print "$un $deux $trois\n"' P $ echo Perl pour plaisir | perl -ne '($un,$deux) = $_ =~ /(p)/gi;print "$un $deux $trois\n"' P p $ echo Perl pour plaisir | perl -ne '($un,$deux,$trois) = $_ =~ /(p)/gi;print "$un $deux $trois\n"' P p p $ echo Perl pour plaisir | perl -ne '@nombre = $_ =~ /(p)/gi;print "@nombre\n"' P p p Et ensuite deuxième question, c'est ce que signifie les ?<= avant les carac1 et carac2, Il s'agit d'un test arrière positif. Donc pour capturer ce que j'ai besoin, je regarde en arrière pour voir si le motif correspond. C'est très pratique quand on parse des gros fichier, puisque le test avant et/ou arrière, positif et/ou negatif, ne consomment pas de texte, ce qui peut rendre une regex plus performante. Pareil pour le ? dans (.*?) Ici il s'agit de la gourmandise du quantificateur * Pour comprendre je vais te donner un exemple
$ echo commentcamarche
commentcamarche
$ echo commentcamarche | perl -ne 'print $1,"\n" if /(c.*c)/'
commentcamarc
$ echo commentcamarche | perl -ne 'print $1,"\n" if /(c.*?c)/'
commentc
Dans le 1er cas .* tu remarques que * avale toute les caractères compris entre le 1er c et le dernier c de notre chaine. En bref * veut dire : prendre zéro caractères, un caractères ou n'importe combien tu peux. Comme * il est gourmand alors il va prendre tout Dans le 2ème cas .*? la capture s'arrête au 1er c rencontré. *? veut dire : prend zéro caractères, un caractère, mais content toi avec le minimum. On peut tirer la conclusion qu'un quantificateur minimal préfère la satisfaction à la gourmandise Une autre situation ça sera: la récupération de la chaine entre l'avant dernier et le dernier c En ce cas on va écrire comme ça $ echo commentcamarche | perl -ne 'print $1,"\n" if /.*(c.*c)/' camarc D'abord la regex va avaler tout grace à .* et ensuite il sera obliger de céder sous contrainte le 1er c rencontrer qui est le dernier dans la chaine. Une fois que la regex a récupéré le dernier c va essayer d'avaler encore des caractères pour trouver un autre c, mais comme elle ne le trouve pas le .* de début va céder encore un caractère et ainsi de suite jusqu'à quand c.*c et satisfait Bon, j'espère que tu as compris un peu :-)) lami20j |
Merci beaucoup pour tes explications.
print("Faites vos choix :\n");
print("Exemple : 1 4\n");
print("1 - afficher toto\n");
print("2 - afficher tata\n");
print("3 - afficher titi\n");
print("4 - afficher tutu\n");
@choix =<stdin>=~ /\d/g;
$i =0;
while (@choix[$i] =~ /\d/)
{
if (@choix[$i] == "1")
{
print("toto\n");
$i++;
}
elsif (@choix[$i] == "2")
{
print("tata\n");
$i++;
}
elsif (@choix[$i] == "3")
{
print("titi\n");
$i++;
}
elsif (@choix[$i] == "4")
{
print("tutu\n");
$i++;
}
else
{
print("@choix[$i] n'est pas un choix correct\n");
$i++;
}
}
Ou bien y'a peut etre une methode plus simple qui existe (sachant que je n'ai pas acces a l'instruction switch) Merci :) |
Tiens j'aurais une autre question :D
foreach $var (@choix)
{
if ($var <=0 || $var > $nb_choix)
{
print("commande pas valide\n");
}
else
{
print("commande lancé : $var");
}
}
(nb_choix) etant le nombre de choix total présent Comment je pourrais rajouter un check pour que l'utilisateur ne rentre pas 2 fois la meme commande? |
Je viens d'entrer à la maison.
|
Pour ma question 4, idealement, j'aimerais un menu dans lequel l'utilisateur pourrait choisir 1, plusieurs ou tous les choix proposés.
@choix =<stdin>=~ /\d/g; et avec le foreach, je traite l'ensemble de ses choix. Par contre, dans les commandes que j'execute, je ne peux pas executer 2 fois la meme. D'ou ma question dans le message 5. Sais tu ou je pourrais acheter une bonne matraque? Bon... d'accord, d'accord, je veux bien plutot essayer de traiter les erreurs de l'utilisateur :) En tout cas, merci beaucoup pour ton aide. |
Bon, je te donne un exemple pour l'étudier, ensuite si tu pense à concevoir quelque chose il faut me dire ce que tu veux faire.
#!/usr/bin/perl
use strict;use warnings;
print "*" x 16 ,"\n";
print "* MENU *\n";
print "*" x 16 ,"\n";
print <<'FIN';
1 - Afficher toto
2 - Afficher tata
3 - Afficher titi
4 - Afficher tutu
FIN
print "Choisissez une ou plusieurs options séparéés par un espace [ ex : 1 3 4 ] : ";
chomp (my $choix = <STDIN>);
my @choix = split " ",$choix;
my %h = (
1 => 'toto',
2 => 'tata',
3 => 'titi',
4 => 'tutu',
);
SWITCH: {
@choix == 0 and die "Vous devez faire un choix\n";
die "Options inconnue\n" if grep { /\D/ } @choix ;
@choix == 1 && do { print $h{$choix[0]},"\n" ;last SWITCH; };
@choix > 1 && do { local $"="\n";print "@h{@choix}\n";last SWITCH; };
}
__END__
Résultat lami20j@debian:~/trash$ perl ccm.pl **************** * MENU * **************** 1 - Afficher toto 2 - Afficher tata 3 - Afficher titi 4 - Afficher tutu Choisissez une ou plusieurs options séparéés par un espace [ ex : 1 3 4 ] : 1 toto lami20j@debian:~/trash$ perl ccm.pl **************** * MENU * **************** 1 - Afficher toto 2 - Afficher tata 3 - Afficher titi 4 - Afficher tutu Choisissez une ou plusieurs options séparéés par un espace [ ex : 1 3 4 ] : 1 3 toto titi lami20j@debian:~/trash$ perl ccm.pl **************** * MENU * **************** 1 - Afficher toto 2 - Afficher tata 3 - Afficher titi 4 - Afficher tutu Choisissez une ou plusieurs options séparéés par un espace [ ex : 1 3 4 ] : 1 2 3 4 toto tata titi tutu lami20j@debian:~/trash$ perl ccm.pl **************** * MENU * **************** 1 - Afficher toto 2 - Afficher tata 3 - Afficher titi 4 - Afficher tutu Choisissez une ou plusieurs options séparéés par un espace [ ex : 1 3 4 ] : 1 4 toto tutu lami20j@debian:~/trash$ perl ccm.pl **************** * MENU * **************** 1 - Afficher toto 2 - Afficher tata 3 - Afficher titi 4 - Afficher tutu Choisissez une ou plusieurs options séparéés par un espace [ ex : 1 3 4 ] : Vous devez faire un choix lami20j@debian:~/trash$ perl ccm.pl **************** * MENU * **************** 1 - Afficher toto 2 - Afficher tata 3 - Afficher titi 4 - Afficher tutu Choisissez une ou plusieurs options séparéés par un espace [ ex : 1 3 4 ] : 1 2 a Options inconnue lami20j@debian:~/trash$-- lami20j |
Je regarderais ca + en détails demain.
|