|
|
|
|
Bonjour,
Je dois faire quelque chose qui m'a pas l'air très dur mais malheuresement, je n'ai pas la moindre idée de la manière de procéder,
J'ai un fichier textes composés d'une succession de chaines de caractères comme celle ci :
16:26:28 (9.50 MB/s) - `MEGASAVE.tar.gz.14' saved [942668/942668]
16:26:46 (9.60 MB/s) - `MEGASAVE.tar.gz.15' saved [942668/942668]
Mille plus précisément et je souhaite juste extraire 9.50 MB/s et 9.60 MB/s...meme pas dans un tableau, juste récuperer les valeurs...
Je ne connais pas les pointeurs. donc il me faudrait qqchose d'assez simple.
Merci infiniment,
Mon adresse email est vincent_roye@hotmail.com
Apparement tu as plusieurs chaines de caractères séparées par des espaces blancs.
|
Pas d'adresse mail sur le forum s'il vous plaît (enfin moi je dis ça surtout pour toi :p) !
char *str="plop 6"; int x; sscanf(str,"plop %d",&x); arth a oublié de passer le fichier en paramètre du fscanf. Tu peux consulter l'aide ici : http://www.linux-france.org/article/man-fr/man3/scanf-3.html Tu peux t'inspirer de ce post pour voir comment lire un fichier ligne par ligne : http://www.commentcamarche.net/forum/affich-2234751-c-parsing-d-un-fichier Si tu es motivé tu peux utiliser aussi la lib pcre. Ceci dit il y a des langages plus adapté que le C/C++ pour parser des fichiers à l'aide d'expressions régulières, comme le python, le ruby, ou le perl... Bonne chance |
Salut,
16:26:28 (9.50 MB/s) - `MEGASAVE.tar.gz.14' saved [942668/942668] 16:26:46 (9.60 MB/s) - `MEGASAVE.tar.gz.15' saved [942668/942668] Je vais affichier seulement le résultat
#!/usr/bin/perl
#
use warnings;use strict;
# les lignes je les ajoute dans le script après le token __END__
# je lis __END__ avec le handle DATA et j'affiche a l'écran les valeurs
#
while (<DATA>){
print "$1\n" if /.*\((.*)\).*/;
}
__END__
16:26:28 (9.50 MB/s) - `MEGASAVE.tar.gz.14' saved [942668/942668]
16:26:46 (9.60 MB/s) - `MEGASAVE.tar.gz.15' saved [942668/942668] lami20j
P.S. Le code ne fonctionne que sur les 2 lignes ou sur le nombre des lignes que la mémoire peut supporter si la structure est toujours la même |
Ceci dit il y a des langages plus adapté que le C/C++ pour parser des fichiers à l'aide d'expressions régulières, comme le python, le ruby, ou le perl...
|
C'est améliorable en catchant les numéros avec un \d... Idéalement tu peux même écrire ton expression régulière en vérifiant que les numéros passés entre chaque point ne sont pas trop absurdes.
|
Re,
#! /usr/bin/perl use warnings;use strict; # toujours je vais utiliser le handle DATA # 1. utilisation de quantificateur gurmand * while (<DATA>){ print "1. $1\n" if /.*\((.*)\).*/; # dans ce cas j'utilise une regex banale # .* prend n'importe quel caractère 0,1 fois ou ...... # en bref en premier temps .* va avaler tout # ensuite sous contrainte va ceder un par un chaque caractère # jusqu'à quand il trouve la 1ère paranthèse # .* entre paranthèse va faire la même chose mais il sera # de ceder aussi la paranthèse fermante # comme ( et ) sont des metacaractères qui servent au groupement et capture # j'ai utilsé \ pour les trouver littéralement # le dernier .* ne sers pas à grand chose (donc on peut s'abstenir) #} #2. utilisation de la classe de caractères \d qui est équivalente avec [0-9] print "2. $1\n" if / \d\d:\d\d:\d\d # regex reconnaît 16:26:28 \s* # ensuite 0,1 ou n'importe combien d'espaces \( # une paranthèse littérale ( # debut du capture, ici la paranthèse = bestiole regex \d\.\d\d\s*MB\/s # reconnaît une chiffre suit d'un point suit de 2 chiffres # de 0,1 ou plusierus espaces suit de M suit de B suit de slash suit de s ) # fin de la capture \)/x; # paranthèse littérale # la regex: /\d\d:\d\d:\d\d\s*\((\d\.\d\d\s*MB\/s)\)/ #le modificateur x permet d'utiliser des espaces # et des commentaires à l'intérieur de regex #3. utilisation de la classe \d avec quantificateurs {x,y} print "3. $1\n" if / \d{1,2}:\d{1,2}:\d{1,2} # regex reconnaît 16:26:28 # {1,2} veut dire 1 ou 2 chiffres \s* # ensuite 0,1 ou n'importe combien d'espaces \( # une paranthèse littérale ( # debut du capture, ici la paranthèse = bestiole regex \d\.\d{1,2}\s*MB\/s # reconnaît une chiffre suit d'un point suit de 2 chiffres # de 0,1 ou plusierus espaces suit de M suit de B suit de slash suit de s ) # fin de la capture \)/x; # paranthèse littérale #le modificateur x permet d'utiliser des espaces # la regex: /\d{1,2}:\d{1,2}:\d{1,2}\s*\((\d\.\d{1,2}\s*MB\/s)\)/ #le modificateur x permet d'utiliser des espaces # et des commentaires à l'intérieur de regex #4. Utilisation d'une classe complementé [^...] print "4. $1\n" if / \( # paranthèse littérale ( # début de la capture [^()]+ # reconnaît au moins une fois tout caractère qui # n'est ni ( ni ) ) # fin de la capture \)/x; # paranthèse littérale #la regex: /\(([^()]+)\)/ #5. utilisation de test avant (?=motif) et test arrière (?<=motif) print "5. $1\n" if / (?<= # début test arrière \( # on cherche en arrière une paranthèse littérale ouvrante ) # fin test arrière (.*) # on capture si en arrière il y une ( et si avant il ya ) (?= # debut test avant \) # on cherche en avant une ) )/x; # fin de test avant # la regex: /(?<=\()(.*)(?=\))/ #6. utilisation d'une variable et substitution (my $tmp = $_) =~ s/.*\(([^()]+)\).*/$1/; # même regex que 4. print "6. $tmp\n"; } __END__ 16:26:28 (9.50 MB/s) - `MEGASAVE.tar.gz.14' saved [942668/942668] 16:26:46 (9.60 MB/s) - `MEGASAVE.tar.gz.15' saved [942668/942668]Le résultat [lamitest@localhost my_perl_script]$ perl mamiemando.pl 1. 9.50 MB/s 2. 9.50 MB/s 3. 9.50 MB/s 4. 9.50 MB/s 5. 9.50 MB/s 6. 9.50 MB/s 1. 9.60 MB/s 2. 9.60 MB/s 3. 9.60 MB/s 4. 9.60 MB/s 5. 9.60 MB/s 6. 9.60 MB/s [lamitest@localhost my_perl_script]$lami20j |
Re,
#! /usr/bin/perl
use warnings;use strict;
# toujours je vais utiliser le handle DATA
while (<DATA>){
# 1. utilisation de quantificateur gurmand *
print "1. $1\n" if /.*\((.*)\).*/;
#2. utilisation de la classe de caractères \d qui est équivalente avec [0-9]
print "2. $1\n" if /\d\d:\d\d:\d\d\s*\((\d\.\d\d\s*MB\/s)\)/;
#3. utilisation de la classe \d avec quantificateurs {x,y}
print "3. $1\n" if /\d{1,2}:\d{1,2}:\d{1,2}\s*\((\d\.\d{1,2}\s*MB\/s)\)/;
#4. Utilisation d'une classe complementé [^...]
print "4. $1\n" if /\(([^()]+)\)/;
#5. utilisation de test avant (?=motif) et test arrière (?<=motif)
print "5. $1\n" if /(?<=\()(.*)(?=\))/;
#6. utilisation d'une variable et substitution
(my $tmp = $_) =~ s/.*\(([^()]+)\).*/$1/; # même regex que 4.
print "6. $tmp\n";
}
__END__
16:26:28 (9.50 MB/s) - `MEGASAVE.tar.gz.14' saved [942668/942668]
16:26:46 (9.60 MB/s) - `MEGASAVE.tar.gz.15' saved [942668/942668]
lami20j
|
Re,
#! /usr/bin/perl
use warnings;use strict;
# mode slurp
# permet d'avaler le contenu de DATA dans une variable scalaire
# ce qui permet l'utilisation de l'assertion \G
undef $/; # $/ ou $INPUT_RECORD_SEPARATOR ou $RS
# c'est le séparateur d'entrée, par défaut \n
# est consulté par la fonction readline,
# l'operateur <HANDLE> et la fonction chomp
my $txt = <DATA>; # tous le contenu de DATA
pos($txt) = 0; # \G est initialisé à 0
while ($txt =~ /\(/g){
print "$1\n" if $txt =~ /\G(.*)\)/;
}
#/\(/g) detecte une paranthèse ouvrante progressivement
# /\G(.*)\)/
# /\G(.*) capture dans $1 ce que je trouve après la paranthèse ovrante
# \)/ jusqu'à on rencontre une paranthèse fermante
# ce cycle se repete jusqu'à la fin de contenu de $txt
__END__
16:26:28 (9.50 MB/s) - `MEGASAVE.tar.gz.14' saved [942668/942668]
16:26:46 (9.60 MB/s) - `MEGASAVE.tar.gz.15' saved [942668/942668]
lami20j
|