OVH Cloud OVH Cloud

Scanf et les espaces

8 réponses
Avatar
Christophe CLEMENT
Bonjour,

Je suis en train de faire un programme qui demande à l'utilisateur
d'entrer un format d'expression et qui doit ensuite chercher dans une
chaîne les différents éléments demandés.

Par exemple on a la chaine : j'ai 20 pommes dans mon panier

Et l'utilisateur peut écrire j'ai %ARTICLES% dans mon panier, et ça lui
renvoie donc 20 pommes.
Ça permet de rentre le truc facile à l'utilisateur.

Le truc c'est que la chaîne de départ est inconnue au début, et est
également récupérée pendant l'exécution du programme, et aura donc des
formes très variées.

J'ai récupéré sur CPAN String::Scanf, mais je bloque, car lorsque je
fais
@res = sscanf("j'ai %s dans mon panier", "j'ai 20 pommes dans mon
panier");
print join("\n", @res);

Ça n'écrit rien, parce qu'il y a un espace dans "20 pommes". Du coup je
ne sais pas trop quoi faire.


Christophe
--
Pour me répondre, mon email en rot13 : hfrarg [ng] 75018 [qbg] bet

8 réponses

Avatar
Johnny \Gandalf\ Brasseur
Salut Christophe,
Scanf n'est peut etre pas le meilleur choix pour matcher un pattern.
il vaut mieux dans ton cas utiliser une expression réguliere comme ca

perl -e '$v="j`ai 20 pommes dans mon panier";$v=~m/j`ai (.*?) dans mon
panier/;print "[$1,$v]n";'
Ca te retourne dans $1 le sous ensemble qui répond au pattern dans la
clause m/xxx/.
Une fois que tu as $1 , si tu sais quels sont les séparateurs possibles ,
tu peux récupérer les items de $1 avec split.
my @res = split(/ /,$1); # exemple avec un espace
# et apres ton print join("n",@res); si nécessaire...
Ce n'est qu'un exemple.

perl est par essence basé sur ce genre de patterns et ca serait utile de
passer par là. non ?

Cdlt
JoB


Christophe CLEMENT wrote:

Bonjour,

Je suis en train de faire un programme qui demande à l'utilisateur
d'entrer un format d'expression et qui doit ensuite chercher dans une
chaîne les différents éléments demandés.

Par exemple on a la chaine : j'ai 20 pommes dans mon panier

Et l'utilisateur peut écrire j'ai %ARTICLES% dans mon panier, et ça lui
renvoie donc 20 pommes.
Ça permet de rentre le truc facile à l'utilisateur.

Le truc c'est que la chaîne de départ est inconnue au début, et est
également récupérée pendant l'exécution du programme, et aura donc des
formes très variées.

J'ai récupéré sur CPAN String::Scanf, mais je bloque, car lorsque je
fais
@res = sscanf("j'ai %s dans mon panier", "j'ai 20 pommes dans mon
panier");
print join("n", @res);

Ça n'écrit rien, parce qu'il y a un espace dans "20 pommes". Du coup je
ne sais pas trop quoi faire.


Christophe


--
Johnny "gandalf" Brasseur (http://www.perlone.org)

Avatar
Christophe CLEMENT
Le 17/07/2004 vers 17h01, "Johnny "Gandalf" Brasseur"

Scanf n'est peut etre pas le meilleur choix pour matcher un pattern.
il vaut mieux dans ton cas utiliser une expression réguliere comme ca

perl -e '$v="j`ai 20 pommes dans mon panier";$v=~m/j`ai (.*?) dans mon panier/;'


Tu as parfaitement raison, je viens de refaire mon code, c'est plus
clair et surtout ça marche !

Ca te retourne dans $1 le sous ensemble qui répond au pattern dans la
clause m/xxx/.


J'ai justement l'habitude des expressions régulières mais je n'avais
pas encore utilisé de "?".
Tant que j'y suis, est-il possible de récupérer dans un tableau les
différents ensembles qui répondent aux patterns $1, $2, ... ? Afin
d'avoir @tab = ($1, $2, $3, .......).

perl est par essence basé sur ce genre de patterns et ca serait utile de
passer par là. non ?


C'est sûr ! C'est d'ailleur la raison pour laquelle je continue à
l'utiliser aussi souvent !

Christophe
--
Pour me répondre, mon email en rot13 : hfrarg [ng] 75018 [qbg] bet

Avatar
Johnny \Gandalf\ Brasseur
Christophe CLEMENT wrote:

Le 17/07/2004 vers 17h01, "Johnny "Gandalf" Brasseur"

Scanf n'est peut etre pas le meilleur choix pour matcher un pattern.
il vaut mieux dans ton cas utiliser une expression réguliere comme ca
perl -e '$v="j`ai 20 pommes dans mon panier";$v=~m/j`ai (.*?) dans mon
panier/;'
Tu as parfaitement raison, je viens de refaire mon code, c'est plus

clair et surtout ça marche !
Kool !

Ca te retourne dans $1 le sous ensemble qui répond au pattern dans la
clause m/xxx/.
J'ai justement l'habitude des expressions régulières mais je n'avais

pas encore utilisé de "?".
Tant que j'y suis, est-il possible de récupérer dans un tableau les
différents ensembles qui répondent aux patterns $1, $2, ... ? Afin
d'avoir @tab = ($1, $2, $3, .......).
Si tu cherches les différents items compris dans la phrase telle que tu l'as

indiquée c'est assez facile, il te suffit de récupérer le bloc dans un $1
puis de faire un split comme je te l'avais indiqué.
perl est par essence basé sur ce genre de patterns et ca serait utile de
passer par là. non ?
C'est sûr ! C'est d'ailleur la raison pour laquelle je continue à

l'utiliser aussi souvent !
Christophe
un petit exemple ?


$_="J'ai 20 pommes dans mon panier";
m/J'ai (.*?) dans mon panier/;
my @tab = split(/ /,$1);
# ou encore
my @tab = split(/[ t]/,$1);
# ou encore
my @tab = split(/s/,$1);
Tout dépend de ce que tu cherches. s'il y a des espaces , cet exemple
marcher très bien sinon s'il y a autre chose c'est à toi de voir.
L'utilisation de s peut etre utile de même que b pour les bordures de
mots.
Bon amusement

--
Johnny "gandalf" Brasseur (http://www.perlone.org)


Avatar
Christophe CLEMENT
Le 17/07/2004 vers 21h16, "Johnny "Gandalf" Brasseur"

Tant que j'y suis, est-il possible de récupérer dans un tableau les
différents ensembles qui répondent aux patterns $1, $2, ... ? Afin
d'avoir @tab = ($1, $2, $3, .......).


Si tu cherches les différents items compris dans la phrase telle que tu l'as
indiquée c'est assez facile, il te suffit de récupérer le bloc dans un $1
puis de faire un split comme je te l'avais indiqué.


En fait je voulais récupérer les items d'une expression plus complexe
du style

$str =~/j'ai ([0-9]+) (pomme|poire|abricot)(s|) dans mon panier/;

Donc j'ai dans $1 le nombre de fruits, dans $2 le nom du fruit, et dans
$3 la marque du pluriel.
J'aurais voulut avoir un tableau @items tel quel $item[0] eq $1 &&
$item[1] eq $2 && $item[2] eq $3.

Car mon expression régulière peut-être un coup très simple, et un autre
coup très longue et dépasser les 9 items ($1, ...$9). Avoir au final un
tableau me permet de récupérer facilement les éléments avec leur
indice.

Raison: j'ai dans $position le numéro de l'item qui m'intéresse, le
premier item étant zéro.
En supposant que j'ai moins de 9 items je peux faire print ${$position +
1};

Mais je préfèrerais pouvoir faire un print $items[$position];


[snip]

Bon amusement


Merci ;o)


Christophe
--
Pour me répondre, mon email en rot13 : hfrarg [ng] 75018 [qbg] bet


Avatar
Christophe CLEMENT
Le 17/07/2004 vers 19h28, "Christophe CLEMENT" a

[snip]

En fait je répond à ma propre question, même pas besoin de tableau, je
fais comme j'ai dit, si la position de l'item dans l'expression
régulière est $position avec le premier item qui a une valeur de 0, il
suffit de faire ${$position -1} pour récupérer cet item.

Tout simplement :-)

Christophe
--
Pour me répondre, mon email en rot13 : hfrarg [ng] 75018 [qbg] bet
Avatar
Johnny \Gandalf\ Brasseur
Christophe CLEMENT wrote:

Le 17/07/2004 vers 19h28, "Christophe CLEMENT" a
[snip]
En fait je répond à ma propre question, même pas besoin de tableau, je
fais comme j'ai dit, si la position de l'item dans l'expression
régulière est $position avec le premier item qui a une valeur de 0, il
suffit de faire ${$position -1} pour récupérer cet item.
Tout simplement :-)
Christophe
Oui comme je te l'ai indiqué , dans la mesure où tu connais le séparateur un

split te fait la découpe que tu veux et met les éléments dans un tableau.
@tab = split /s/;
# ensuite un
BOUCLE: foreach(@tab) {
/ITEM1/ && do { action1(); last BOUCLE; }
/ITEM2/ && do { action2(); last BOUCLE; }
/ITEM3/ && do { action3(); last BOUCLE; }
...etc
}
te permet de parcourir les items pour les analyser.
Enfin c'est comme ca que je ferais.
Si ca peut aider...
--
Johnny "gandalf" Brasseur (http://www.perlone.org)

Avatar
DominiX
ici même:cdbsgb$7nm$,
Christophe CLEMENT a écrit
Le 17/07/2004 vers 17h01, "Johnny "Gandalf" Brasseur"



...
J'ai justement l'habitude des expressions régulières mais je n'avais
pas encore utilisé de "?".
Tant que j'y suis, est-il possible de récupérer dans un tableau les
différents ensembles qui répondent aux patterns $1, $2, ... ? Afin
d'avoir @tab = ($1, $2, $3, .......).



voir @- et @+ dans perldoc perlvar

-- dominix

Avatar
Patrick Mevzek
J'aurais voulut avoir un tableau @items tel quel $item[0] eq $1 &&
$item[1] eq $2 && $item[2] eq $3.


my @item=($str=~m/..../):

--
Patrick Mevzek . . . . . . Dot and Co (Paris, France)
<http://www.dotandco.net/> <http://www.dotandco.com/>