cerhu > comp.lang.* > comp.lang.perl

kurtz le pirate (29/12/2019, 13h31)
Bonjour,

Je ne sais pas si c'est les fêtes de fin d'année, mais ce ng est bien
vide :(

Bon, le but est de récupérer des nombres dans un fichier texte.
J'en suis la :

open(SRCFILE,"<$working_file") || die("Impossible d'ouvrir le fichier\n");
foreach my $line (<SRCFILE>) {
if (my @AllFloats = ( $line =~ /([-+]?([0-9]*\.[0-9]+|[0-9]+))/g) ) {
print $line;
foreach my $thisFloat (@AllFloats) {
print " > $thisFloat\n";
}
print "\n\n";
}
}
close(SRCFILE);

Ca fonctionne à peu prés bien. J'ai des résultats de ce type :

La ligne "source"
[0.9 p_micro1 rotate 90*y]
Le résulat :
> 0.9
> 0.9
> 1
> 1
> 90
> 90


Premièrement, je ne comprends pas pourquoi les valeurs sont en doubles ?
Le foreach est tout bête :(
Je dois faire une erreur quelque part. Vous voyez ou ?

Deuxièmement, et la c'est plus compliqué car c'est la regexp qui ne
fonctionne pas correctement. la valeur trouvée "1" vient de "p_micro1".
Bien sûr, c'est un nombre, mais il fait parti du nom d'une variable.
La je n'ai aucune piste pour résoudre ce cas.

Une idée ?

Le but final est de mettre en forme tout les nombres trouvés du genre :
..1 deviendra 0.100 par exemple
1 deviendra 1.000
-.5356854 deviendra -0.5356854

je n'en suis pas encore la... a moins qu'il existe déja un module qui
fait ça ?

Merci d'avance et bonnes fêtes.
Marc SCHAEFER (29/12/2019, 13h47)
kurtz le pirate <kurtzlepirate> wrote:
> open(SRCFILE,"<$working_file") || die("Impossible d'ouvrir le fichier\n");


J'ai préféré réécrire, et sur le fichier de test

$ cat un_test
[0.9 p_micro1 rotate 90*y]
[-0.9 p_micro1 rotate 90*y]
[-0.9 p_micro1 rotate 90*y]
[+0.9 p_micro1 rotate 90*y]
[-.536854 p_micro1 rotate 90*y]

la sortie semble pas mal:

$ ./a.pl
> 0.900
> -0.900
> -0.900
> 0.900
> -0.537


$ cat a.pl
! /usr/bin/perl

use strict;
use warnings;

my $working_file = "un_test";

open(SRCFILE, '<', $working_file)
or die("Impossible d'ouvrir le fichier: " . $working_file . "\n");

my @all_floats;
while (my $line = <SRCFILE>) {
chomp $line;

if ($line =~ /^\[([+\-]{0,1}\d{0,1}+(\.\d+)}{0,1})/) {
push(@all_floats, $1);
}
}

close(SRCFILE); # err. ign.

map { printf "\> %.3f\n", $_ } @all_floats;
kurtz le pirate (29/12/2019, 16h41)
On 29/12/2019 12:47, Marc SCHAEFER wrote:
> kurtz le pirate <kurtzlepirate> wrote:
>> open(SRCFILE,"<$working_file") || die("Impossible d'ouvrir le fichier\n");

> J'ai préféré réécrire, et sur le fichier de test
> ...


merci pour ta réponse... mais cela ne semble pas fonctionner :(

les lignes ne commencent pas forcément par un nombre $line =~ /^....

si l'on prend cette ligne "source" :
object { sheet(Cl_SI_D65*2000)scale <100,.1,100> translate 0.9*y}

j'obtiens :
[..]
> 100
> 0.9
> 0.9


si l'on fait abstraction des valeurs en double, on a bien les 6 nombres.
le "65" n'est pas bon car il fait parti du nom Cl_SI_D65.

je n'ai aucun résultat avec ton exemple sur mon fichier.
d'ailleur, même avec ta sortie sur le même exemple :
[0.9 p_micro1 rotate 90*y]
tu ne récupères que le premier nombre 0.9 et pas le deuxième 90.
Marc SCHAEFER (29/12/2019, 17h24)
kurtz le pirate <kurtzlepirate> wrote:
> merci pour ta réponse... mais cela ne semble pas fonctionner :(


Elle fonctionne sur mon exemple. Tu n'avais pas expliqué que tu veux
les nombres, mais pas les nombres faisant partie d'identifiants, et
qu'il y a plusieurs nombres par ligne.

Dans ce cas, voici quelques pistes:
- utiliser le modificateur /ge, du style:
$line =~ s/.../push(@..., $1)/ge;
- utiliser un pré-remplacement supprimant tous les identificateurs
kurtz le pirate (29/12/2019, 17h49)
On 29/12/2019 16:24, Marc SCHAEFER wrote:
> kurtz le pirate <kurtzlepirate> wrote:
> Elle fonctionne sur mon exemple. Tu n'avais pas expliqué que tu veux
> les nombres, mais pas les nombres faisant partie d'identifiants, et
> qu'il y a plusieurs nombres par ligne.
> Dans ce cas, voici quelques pistes:
> - utiliser le modificateur /ge, du style:
> $line =~ s/.../push(@..., )/ge;
> - utiliser un pré-remplacement supprimant tous les identificateurs


merci. j'avance un peu :

foreach my $line (<SRCFILE>) {
if ( $line =~ /([-+]?([0-9]*\.[0-9]+|[0-9]+))/) {
print $line;
$line =~ s/([-+]?([0-9]*\.[0-9]+|[0-9]+))/sprintf ("%.3f",$1)/ge;
print $line;
print "\n\n";
}
}

qui me donne :

source :
object { sheet(Cl_SI_D65*2000)scale <100,.1,100> translate 0.9*y}

resultat :
object { sheet(Cl_SI_D65.000*2000.000)scale <100.000,0.100,100.000>
translate 0.900*y}

encore le problème des identifants : Cl_SI_D65.
kurtz le pirate (29/12/2019, 21h00)
On 29/12/2019 16:49, kurtz le pirate wrote:

> encore le problème des identifants : Cl_SI_D65.


que j'ai à peu près résolut comme ça :

$line =~ s/([-+]?([0-9]*\.[0-9]+|[0-9]+))/fnFormat($1)/ge;

et la fonction :
sub fnFormat {
my $n = shift;
($n =~ /\./ ? sprintf ("%.3f",$n) : $n)
}

j'avance.
Nicolas George (29/12/2019, 21h24)
kurtz le pirate , dans le message
<5e088e79$0$20339$426a74cc>, a écrit :
> Premièrement, je ne comprends pas pourquoi les valeurs sont en doubles ?


Tu as deux paires de parenthèses, donc deux captures par nombre reconnu.

> Le foreach est tout bête :(
> Je dois faire une erreur quelque part. Vous voyez ou ?
> Deuxièmement, et la c'est plus compliqué car c'est la regexp qui ne
> fonctionne pas correctement. la valeur trouvée "1" vient de "p_micro1".
> Bien sûr, c'est un nombre, mais il fait parti du nom d'une variable.
> La je n'ai aucune piste pour résoudre ce cas.


Regarde du côté de \b.
Discussions similaires
Lecture d'un nombre à virgule flottante

virgule flottante et FLT_EPSILON

Debordement en virgule flottante

Exception de virgule flottante


Fuseau horaire GMT +2. Il est actuellement 12h21. | Privacy Policy