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

Newbie : problème de regex

4 réponses
Avatar
ctemp1
Bonjour,

Je suis en train de formater les sorties d'un tableau.

Celui-ci est composé de mots et chiffres avec virgules.

Je me serts de sprintf pour fixer à 2 les décimaux.

De cette manière je concatène chaque indice su tableau à une variable
$texte.

Ex : @tab( "Un", 2.4785, 5.1255, "Deux", 4.7885, 7.7774 );
$texte = "";
foreach ( $tab ) {
si c'est un chiffre -> $texte .= sprintf "%.2f", $_." ";
sinon $texte .= $_." ";
}

J'obtient quelque chose comme :
Un 2.47 5.1255 Deux 4.78 7.77

Là je voudrais parser cette variable et j'ai un truc de fous :
si je fait $texte =~ s/(\s)/ : /g;
ou $texte =~ s/(\d+)(.)(\d+)(\s)/ : /g
Je n'ai aucun problème.
Mais quand j'essaie de faire $texte =~ s/(\s)(\d+)/ : /g;
Là je n'ai aucun changement du tout.

Je sais qu'il faudrait voir la totalité du programme pour voir
l'erreur, mais je voudrais surtout savoir si c'est un cas connu et
s'il y a une astuce.

Merci.

C. Tobini

4 réponses

Avatar
Rue des Prairies
C. Tobini wrote:

Bonjour,

Je suis en train de formater les sorties d'un tableau.

Celui-ci est composé de mots et chiffres avec virgules.

Je me serts de sprintf pour fixer à 2 les décimaux.

De cette manière je concatène chaque indice su tableau à une variable
$texte.

Ex : @tab( "Un", 2.4785, 5.1255, "Deux", 4.7885, 7.7774 );
$texte = "";
foreach ( $tab ) {
si c'est un chiffre -> $texte .= sprintf "%.2f", $_." ";
sinon $texte .= $_." ";
}

J'obtient quelque chose comme :
Un 2.47 5.1255 Deux 4.78 7.77

Là je voudrais parser cette variable et j'ai un truc de fous :
si je fait $texte =~ s/(s)/ : /g;
ou $texte =~ s/(d+)(.)(d+)(s)/ : /g
Je n'ai aucun problème.
Mais quand j'essaie de faire $texte =~ s/(s)(d+)/ : /g;
Là je n'ai aucun changement du tout.

Je sais qu'il faudrait voir la totalité du programme pour voir
l'erreur, mais je voudrais surtout savoir si c'est un cas connu et
s'il y a une astuce.

Merci.

C. Tobini
Bonjour,


Qu'entends tu par "je n'ai aucun changement du tout" ?

Dis ce que tu voudrais obtenir, parce que tes regexp sont correctes mais
ne font peut-être pas ce que tu voudrais.

Olivier.

Avatar
ctemp1
En fait j'ai un tableau de la forme @tab( [], [], [] ) dont l'adresse
est passée par référence à une fonction.

Par une double boucle for() je concatène chaque élement de chaque
tableau anonyme à une variable ($texte).

Pour chaque élement, si celui-ci est un nombre : $texte .= sprintf
"%.2f", $tab->[$i][$j] sinon il est concaténé tel quel : $texte $tab[$i][$j];

A la fin de chaque boucle, j'ai normalement chaque tableau anonyme
stocké dans la variable qui se présente sous la forme $texte = Valeur
1.00 2.45 AT 5.00 4.41

Les nombres 1.00 et 5.00 sont des entiers, je voudrais donc les sortir
sans virgule, j'emploie un regex :
$texte =~ s/(d+)(.)(d+)(s)(d+)(.)(d+)/$1 - $5.$7/g;
De cette manière la sortie est Valeur 1 - 2.45 AT 5 - 4.41 puisque
j'ai bien un nombre / un point / un nombre / un espace / un nombre /
un point /un espace (je sais, ça ne doit pas etre la méthode la plus
élégante :)).

Or, en tripatouillant le regex j'arrive bien à sortir les nombres, les
nombres à virgule, les espaces... mais des lors que je rentre un
espace suivi d'un nombre ou même un mot, il n'y a aucune modification
en sortie. En revanche, si je passe $texte en variable globale, il n'y
a aucun problème (?) mais à ce moment je ne peux plus agir sur la
boucle.

Par ailleurs j'ai modifié le script et il s'avère qu'en essayant de
mettre la variable $texte dans un tableau ( push(@array, $texte) ) je
m'aperçois que ce n'est pas toute l'expression qui est stockée en
valeur 0 du tableau, mais chaque mot, comme si j'avais fait
@array=split, $texte. Là je ne comprends vraiment plus ! J'ai fait des
essais qui marchaient parfaitement.
Cela aurait-il un rapport avec le fait que j'ai concaténé les élements
d'un tableau (j'ai pourtant fait des essais qui marchaient
parfaitement).

Merci pour la patience de lire juqu'au bout :)

C. Tobini
Avatar
Rue des Prairies
C. Tobini wrote:
En fait j'ai un tableau de la forme @tab( [], [], [] ) dont l'adresse
est passée par référence à une fonction.

Par une double boucle for() je concatène chaque élement de chaque
tableau anonyme à une variable ($texte).

Pour chaque élement, si celui-ci est un nombre : $texte .= sprintf
"%.2f", $tab->[$i][$j] sinon il est concaténé tel quel : $texte > $tab[$i][$j];

A la fin de chaque boucle, j'ai normalement chaque tableau anonyme
stocké dans la variable qui se présente sous la forme $texte = Valeur
1.00 2.45 AT 5.00 4.41

Les nombres 1.00 et 5.00 sont des entiers, je voudrais donc les sortir
sans virgule, j'emploie un regex :
$texte =~ s/(d+)(.)(d+)(s)(d+)(.)(d+)/$1 - $5.$7/g;
De cette manière la sortie est Valeur 1 - 2.45 AT 5 - 4.41 puisque
j'ai bien un nombre / un point / un nombre / un espace / un nombre /
un point /un espace (je sais, ça ne doit pas etre la méthode la plus
élégante :)).


Pas tout à fait, le point . représente un caractère quelconque si tu
veux un point tu dois coder .
Ne pourrais-tu pas déterminer si c'est un entier dans ta première boucle
? ce qui éviterait de faire 2 substitutions.



Or, en tripatouillant le regex j'arrive bien à sortir les nombres, les
nombres à virgule, les espaces... mais des lors que je rentre un
espace suivi d'un nombre ou même un mot, il n'y a aucune modification
en sortie. En revanche, si je passe $texte en variable globale, il n'y
a aucun problème (?) mais à ce moment je ne peux plus agir sur la
boucle.


Je ne vois pas ce que tu veux dire.


Par ailleurs j'ai modifié le script et il s'avère qu'en essayant de
mettre la variable $texte dans un tableau ( push(@array, $texte) ) je
m'aperçois que ce n'est pas toute l'expression qui est stockée en
valeur 0 du tableau, mais chaque mot, comme si j'avais fait
@array=split, $texte. Là je ne comprends vraiment plus ! J'ai fait des
essais qui marchaient parfaitement.


?????????

Cela aurait-il un rapport avec le fait que j'ai concaténé les élements
d'un tableau (j'ai pourtant fait des essais qui marchaient
parfaitement).

Merci pour la patience de lire juqu'au bout :)

C. Tobini


Donne des exemples précis et le bout de code, là je ne sais pas quoi te
dire.

Olivier.

Avatar
ctemp1
Bon en fait j'ai 'trouvé' (mais j'ai honte).

Il y avait plusieurs boucles imbriquées et je concaténais des élements
à chaque tour de boucle.

Je n'avais pas vu que mon regex était placé dans la boucle supérieure
à celle dans laquelle il aurait du être.

Du coup comme ma variable était alimentée en permanence, il n'y avait
pas de correspondance avec ce que je cherchais...

Ca doit être fréquent, je pense en programmation newbiesque.

En tout cas merci d'avoir proposé votre aide.

Certainement à bientôt sur le forum :)

C. Tobini