Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Extraction nombre décimaux.

1 view
Skip to first unread message

kurtz le pirate

unread,
Oct 23, 2022, 4:56:53 AM10/23/22
to

Bonjour,

Je troune en rond depuis quelques temps sur l'extraction de nombre
décimaux depuis un fichiers. je n'arrive pas à capturer le signe.

Le bout de code :

my $countLine = 1;
my @floatnum;
foreach my $line (<SRCFILE>) {
chomp $line;
printf("%4d : %s\n", $countLine, $line);
@floatnum = $line =~ /[-+]?([0-9]*\.[0-9]+|[0-9]+)/g;
# @floatnum = $line =~ /($RE{num}{real})/g;
# @floatnum = $line =~ /([+-]?\d+(\.\d+)?)/g;
if (@floatnum) {
print "float = $_\n" foreach (@floatnum);
}
$countLine++;
}

Surtout (!) pour les nombres négatifs.
Le "+" pour les nombres positifs n'existe jamais.


Exemple :
#declare x = -.168452; #declare y = 0.456; #declare z = -5.4563e6;

Je récupère :
float = .168452
float = 0.456
float = 5.4563
float = 6


Pas de signe.
Faut aussi que je m'occupe des exposants mais après ...


Merci pour vos suggestions.

--
kurtz le pirate
compagnie de la banquise

Olivier Miakinen

unread,
Oct 23, 2022, 5:32:39 AM10/23/22
to
Bonjour,

Le 23/10/2022 10:56, kurtz le pirate a écrit :
>
> Je troune en rond depuis quelques temps sur l'extraction de nombre
> décimaux depuis un fichiers. je n'arrive pas à capturer le signe.

Je suggère :
/(?=[-+]?[0-9.])([-+]?)([0-9]*)(?:\.([0-9]+))?(?:e([0-9]+))?/g

L'assertion (?=[-+]?[0-9.]) au début permet de ne considérer que ce qui
ressemble déjà à un nombre (sinon ça matchera aussi la chaîne vide).

> @floatnum = $line =~ /[-+]?([0-9]*\.[0-9]+|[0-9]+)/g;
> # @floatnum = $line =~ /($RE{num}{real})/g;
> # @floatnum = $line =~ /([+-]?\d+(\.\d+)?)/g;

Tu ne peux capturer qu'une seule chose à la fois ???

> Exemple :
> #declare x = -.168452; #declare y = 0.456; #declare z = -5.4563e6;
>
> Je récupère :
> float = .168452
> float = 0.456
> float = 5.4563
> float = 6

Je récupère :

-.168452
"-"
""
"168452"
""

0.456
""
"0"
"456"
""

-5.4563e6
"-"
"5"
"4563"
"6"


--
Olivier Miakinen

Marc SCHAEFER

unread,
Oct 23, 2022, 9:15:49 AM10/23/22
to
kurtz le pirate <kurtzl...@free.fr> wrote:
> @floatnum = $line =~ /[-+]?([0-9]*\.[0-9]+|[0-9]+)/g;

comme [-+]? n'est pas entre (), Perl ne va pas l'extraire et il ne va
pas finir dans le tableau.

@floatnum = $line =~ /([-+]?[0-9]*\.[0-9]+|[0-9]+)/g;

démo:

schaefer@reliand:/tmp$ ./a.pl
1.2
1.2
1.2 4.5
1.2, 4.5
-1.2
-1.2
-1.2 4.5
-1.2, 4.5

schaefer@reliand:/tmp$ cat a.pl
#! /usr/bin/perl

use strict;
use warnings;

my $re = '^[-+]';

while (my $line = <STDIN>) {
my @f = $line =~ /([-+]?[0-9]*\.[0-9]+|[0-9]+)/g;

print join(', ', @f), "\n";
}

Marc SCHAEFER

unread,
Oct 23, 2022, 9:17:15 AM10/23/22
to
Olivier Miakinen <om+...@miakinen.net> wrote:
> /(?=[-+]?[0-9.])([-+]?)([0-9]*)(?:\.([0-9]+))?(?:e([0-9]+))?/g

Je me demande si p.ex. avec la ligne "4.5 -1.2" ça risque
de créer un tableau (4.5, -, 1.2).

Richard Hachel

unread,
Oct 23, 2022, 9:18:56 AM10/23/22
to
C'est tout ce que tu te demandes, toi le génie suisse? ? ?

R.H.

Marc SCHAEFER

unread,
Oct 23, 2022, 9:25:45 AM10/23/22
to
kurtz le pirate <kurtzl...@free.fr> wrote:
> @floatnum = $line =~ /[-+]?([0-9]*\.[0-9]+|[0-9]+)/g;

comme [-+]? n'est pas entre (), Perl ne va pas l'extraire et il ne va
pas finir dans le tableau.

@floatnum = $line =~ /([-+]?[0-9]*\.[0-9]+|[0-9]+)/g;

démo:

schaefer@reliand:/tmp$ ./a.pl
1.2
1.2
1.2 4.5
1.2, 4.5
-1.2
-1.2
-1.2 4.5
-1.2, 4.5

schaefer@reliand:/tmp$ cat a.pl
#! /usr/bin/perl

use strict;
use warnings;

Olivier Miakinen

unread,
Oct 23, 2022, 2:33:34 PM10/23/22
to
Je ne sais pas trop comment ça fonctionne en perl, mais en pricipe
ça devrait plutôt créer un tableau du style :
( ("4.5", "", "4", "5", ""), ("-1.2", "-", "1", "2", "") )

Du moins si l'item 0 pour chaque capture est la séquence complète qui
a été capturée par la regexp, et si les items 1, 2, 3 et 4 correspondent
à chaque paire de parenthèses capturantes.

--
Olivier Miakinen

Olivier Miakinen

unread,
Oct 23, 2022, 2:35:14 PM10/23/22
to
Le 23/10/2022 15:18, Richard Hachel a écrit :
>
> C'est tout ce que tu te demandes, toi le génie suisse? ? ?

Qu'en penses-tu, toi le prétendu multi-nobélisé ? Au fait quels prix
Nobel prétends-tu avoir eu, et en quelles années ?


--
Olivier Miakinen

Marc SCHAEFER

unread,
Oct 24, 2022, 2:52:53 AM10/24/22
to
Olivier Miakinen <om+...@miakinen.net> wrote:
> Je ne sais pas trop comment ça fonctionne en perl, mais en pricipe
> ça devrait plutôt créer un tableau du style :
> ( ("4.5", "", "4", "5", ""), ("-1.2", "-", "1", "2", "") )

En Perl, on a ce qu'on appelle le contexte de liste, ce qui met à plat
les tableaux. Ce qui permet en une opération de mettre toutes les
occurences (/g) de parenthèses dans le même tableau.

exemple:

$ ./a.pl
bad: schaefer, alphanet.ch, toto, truc.org

avec a.pl:
schaefer@reliand:/tmp$ ./a.pl
bad: schaefer, alphanet.ch, toto, truc.org
good: scha...@alphanet.ch, to...@truc.org

avec:

use strict;
use warnings;

my $s = 'scha...@alphanet.ch to...@truc.org';

my @bad = $s =~ /([^\@\s]+)\@([^\s]+)/g;

print "bad: ", join(', ', @bad), "\n";

my @good = $s =~ /([^\s]+)/g;
#my @good = split /\s+/, $s;
print "good: ", join(', ', @good), "\n";

> Du moins si l'item 0 pour chaque capture est la séquence complète qui
> a été capturée par la regexp, et si les items 1, 2, 3 et 4 correspondent
> à chaque paire de parenthèses capturantes.

En Perl, ça correspond à $1, $2, $3, ... pour chacune des parenthèses.
C'est tout. On peut bien sûr imbriquer une toute grande parenthèse qui
sera alors $1. $0 en Perl est toujours le nom du programme tel qu'il a
été appelé (équivalent en C de argv[0])

Si l'on n'aime pas ça, on peut aussi utiliser la variante suivante:

my @tableau;

# modifie $s
$s =~ s/([^\@\s]+)\@([^\s]+)/process_it($1, $2)/ge;

avec

sub process_it {
my ($user, $domain) = @_;

push(@tableau, [ $user, $domain ]);
}

Dans ce cas on aura @tableau = ([ 'schaefer', 'alphanet.ch' ], [ 'toto',
'truc.org' ]) que l'on peut reconvertir en ('scha...@alphanet.ch',
'to...@truc.org') avec:

# usage de la variable par défaut $_, ici en tant que
# référence sur un tableau
@tableau = map { $_->[0] . '@' . $_->[1] } @tableau;

ou encore remplacer process_it par un simple:

sub process_it {
my ($user, $domain) = @_;

push(@tableau, $user . '@' . $domain);
}

PS: en Perl () c'est une liste/tableau; [] une référence sur une
liste/tableau, symétriquement pour les hashes () et {}.

Marc SCHAEFER

unread,
Oct 24, 2022, 2:53:28 AM10/24/22
to
Olivier Miakinen <om+...@miakinen.net> wrote:
> Je ne sais pas trop comment ça fonctionne en perl, mais en pricipe
> ça devrait plutôt créer un tableau du style :
> ( ("4.5", "", "4", "5", ""), ("-1.2", "-", "1", "2", "") )

En Perl, on a ce qu'on appelle le contexte de liste, ce qui met à plat
les tableaux. Ce qui permet en une opération de mettre toutes les
occurences (/g) de parenthèses dans le même tableau.

exemple:

$ ./a.pl
bad: schaefer, alphanet.ch, toto, truc.org
good: scha...@alphanet.ch, to...@truc.org

avec a.pl:

use strict;
use warnings;

my $s = 'scha...@alphanet.ch to...@truc.org';

my @bad = $s =~ /([^\@\s]+)\@([^\s]+)/g;

print "bad: ", join(', ', @bad), "\n";

my @good = $s =~ /([^\s]+)/g;
#my @good = split /\s+/, $s;
print "good: ", join(', ', @good), "\n";

> Du moins si l'item 0 pour chaque capture est la séquence complète qui
> a été capturée par la regexp, et si les items 1, 2, 3 et 4 correspondent
> à chaque paire de parenthèses capturantes.

kurtz le pirate

unread,
Oct 24, 2022, 11:27:43 AM10/24/22
to
On 23/10/2022 15:15, Marc SCHAEFER wrote:
> ...
> @floatnum = $line =~ /([-+]?[0-9]*\.[0-9]+|[0-9]+)/g;
> ...

oui, ça marche bien :) Merci !


par contre, comme ça marche bien, je suis tombé sur une autre
problème avec cette ligne par exemple :

CIE_ColorSystemWhitepoint(ColSys,Blackbody2Whitepoint(4000))

ça capture le "2" dans Blackbody2Whitepoint et de manière générale, les
nombres dans le nom des variables... je sens que ça va être sport.


encore merci Marc.

Olivier Miakinen

unread,
Oct 24, 2022, 11:57:54 AM10/24/22
to
Le 24/10/2022 17:27, kurtz le pirate a écrit :
>> ...
>> @floatnum = $line =~ /([-+]?[0-9]*\.[0-9]+|[0-9]+)/g;
>
> par contre, comme ça marche bien, je suis tombé sur une autre
> problème avec cette ligne par exemple :
>
> CIE_ColorSystemWhitepoint(ColSys,Blackbody2Whitepoint(4000))
>
> ça capture le "2" dans Blackbody2Whitepoint et de manière générale, les
> nombres dans le nom des variables... je sens que ça va être sport.

@floatnum = $line =~ /(?<!\w)([-+]?[0-9]*\.[0-9]+|[0-9]+)(?!\w)/g;


--
Olivier Miakinen

kurtz le pirate

unread,
Oct 25, 2022, 10:58:34 AM10/25/22
to
On 24/10/2022 17:57, Olivier Miakinen wrote:
> ...>
> @floatnum = $line =~ /(?<!\w)([-+]?[0-9]*\.[0-9]+|[0-9]+)(?!\w)/g;
>

Plus rapide que l'éclair !
Je n'avais même pas commencé à chercher.


Merci Olivier.

Olivier Miakinen

unread,
Oct 26, 2022, 9:58:48 AM10/26/22
to
Le 25/10/2022 à 16:58, kurtz le pirate a écrit :
>
>> @floatnum = $line =~ /(?<!\w)([-+]?[0-9]*\.[0-9]+|[0-9]+)(?!\w)/g;
>
> Plus rapide que l'éclair !
> Je n'avais même pas commencé à chercher.

:-)

J'adoooore les assertions. Ça a été un immense progrès dans les regexp
(Perl et PCRE).


--
Olivier Miakinen
0 new messages