IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Récupérer motif entre des guillemets


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 236
    Par défaut Récupérer motif entre des guillemets
    Bonjour,

    Je parcours un fichier et dois récupérer tous ce qu'il y a d'écrit entre guillemets.
    Et enregistrer chaque valeurs récupérées dans un tableau.

    Voici un exemple de texte en entrée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	Mazotu: 4.15"
    	Vivou: 1.885"
    		"Première chaine à récupérer" External References? No
    		Reject "Deuxième chaine à récupérer" Instances? Yes
    		Enable Runtime "Troisième
    		chaine à récupérer qui est sur 2 ligne"? No
    		Use Release 4.0 Scope Rules? No
    				Font Name: "Quatrième chaine à récupérer" gfgfg || "Cinquième chaine à récupérer"
    				Font Name: "Sixième chaine à récupérer" gfgfg || "Septième chaine
    				à récupérer sur deux lignes"
    Mon code doit me donner en sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Tab[0]		Première chaine à récupérer
    Tab[1]		Deuxième chaine à récupérer
    Tab[2] 		Troisième chaine à récupérer qui est sur 2 ligne
    Tab[3]		Quatrième chaine à récupérer
    Tab[4]		Cinquième chaine à récupérer
    Tab[5]		Sixième chaine à récupérer 
    Tab[6]		Septième chaine à récupérer sur deux lignes
    J'ai essayé de faire avec une cherche par bloc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $in_bloc = ($ligne =~ m/\"/) .. ($ligne =~ m{\w+\"});
    Mais ça marche mal car il y a des guillemets partout...

    Quelqu'un serait me venir en aide svp ?

  2. #2
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    Tu peux continuer dans la même voie que celle que je t'ai indiquée sur l'autre post:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    print "$1\n" if $line =~ /"([^"]+)"/; # récupère 4ème chaine
    print "$2\n" if $line =~ /"([^"]+)"[^"]*"([^"]+)"/; # récupère 5ème chaine
    print "$3\n" if ...
    Mais ça va vite devenir ingérable.

    De plus, comme je te l'ai déjà dit, les chaines multilignes posent vraiment un problème, d'autant plus que l'on a du mal à les identifier et à les distinguer d'autres bizarretés dans ton fichier:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Mazotu: 4.15"
    Vivou: 1.885"
    Peut être considéré comme une chaîne multiligne. Comment les reconnaître?

  3. #3
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 236
    Par défaut
    Merci de t'intéresser à mon problème

    C'est tout simple,

    Une chaine multiligne ou simple par commence par une guillemet double et fini par une guillemet double.

    Pour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Mazotu: 4.15"
    Vivou: 1.885"
    Ne pas traiter c'était un cas d'exception que je gérerai autrement.

    Donc quand sur ma ligne j'ai une guillemet je recupère tout ce qu'il y a jusqu’à la guillemet d'après.
    Sur une simple ligne ou multiligne il peut y en avoir plusieurs exemple : "Cinquième chaine à récupérer" ou la "Septième chaine à récupérer sur deux lignes"

    Est ce plus clair ?

  4. #4
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    On peut essayer une reconnaissance progressive avec fusion de la ligne avec la ligne suivante quand on se retrouve avec un seul guillemet et appel récursif.

    Un truc dans ce goût-là (code fait à la va-vite et pas du tout testé):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    while (<in>) {
        chomp;
    	next if /"$/;  #elimine les premières lignes se terminant par "
    	next unless /"/;  #elimine les lignes sans guillemets
    	parcourt_ligne ($_);
    }
     
    sub parcourt_ligne {
    	my $ligne = shift;
    	while ( $ligne =~ /"([^"]+)"/ ) {
    	 	print "$1\n";
    	 	$ligne =~ s/[^"]+"([^"]+)"//; # supprime le debut de la ligne jusqu'à ce qui a déjà été reconnu
    	 }
    	 if ($ligne =~ /=/) { #guillemet orphelin, donc chaine multiligne
    	 	$ligne = $ligne . <in>; #recuperation ligne suivante
    	 	parcourt_ligne ($ligne);
    	 }
    }

    Il y a certainement un bug ici ou là, mais ça devrait à peu près marcher.

  5. #5
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    Bonjour, une version corrigée et testée rapidement:

    Données:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    		"Premiere chaine a recuperer" External References? No
    		Reject "Deuxieme chaine a recuperer" Instances? Yes
    		Enable Runtime "Troisieme
    		chaine a recuperer qui est sur 2 ligne"? No
    		Use Release 4.0 Scope Rules? No
    				Font Name: "Quatrieme chaine a recuperer" gfgfg || "Cinquieme chaine a recuperer"
    				Font Name: "Sixieme chaine a recuperer" gfgfg || "Septieme chaine
    				a recuperer sur deux lignes"

    Code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    use strict;
    use warnings;
     
    my $file_in = "input.txt";
    open FILE_IN, "<$file_in" or die "cannot open $file_in $!";
     
    while (<FILE_IN>) {
    	chomp;
    	s/\r//; # enlève retours chariot Windows 
    	# next if /"$/;  cette instruction doit être enlévée, sinon on perd 4 et 5 eme chaines
    	next unless /"/;  #elimine les lignes sans guillemets
    	parcourt_ligne ($_);
    }
     
    sub parcourt_ligne {
    	my $ligne = shift;
    	while ( $ligne =~ /"([^"]+)"/ ) {
    	 	print "$1\n";
    	 	$ligne =~ s/[^"]+"([^"]+)"//; # supprime le debut de la ligne jusqu'à ce qui a déjà été reconnu
    	 }
    	 if ($ligne =~ /"/) { #guillemet orphelin, donc chaine multiligne
    	 	my $new_line = <FILE_IN>;
    	 	chomp $new_line;
    	 	$new_line =~ s/\s+/ /;
    	 	my $line = $ligne . $new_line; #recuperation ligne suivante
    	 	parcourt_ligne ($line);
    	 }
    }
    Et le résultat:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ perl guillemets.pl
    Premiere chaine a recuperer
    Deuxieme chaine a recuperer
    Troisieme chaine a recuperer qui est sur 2 ligne
    Quatrieme chaine a recuperer
    Cinquieme chaine a recuperer
    Sixieme chaine a recuperer
    Septieme chaine a recuperer sur deux lignes

  6. #6
    Membre éclairé
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 236
    Par défaut
    Bonjour,

    Merci énormément Lolo 78.
    Puis je te demander une dernière petite aide.

    1) Je ne comprend pas tout dans ton code.
    J'aimerai vraiment le comprendre parfaitement afin de pouvoir le faire évoluer et m'en servir correctement.

    Peux tu me commenter de façon très détaillé ce que tu as fais pas à pas s'il te plait.

    Par exemple :

    /"([^"]+)"/ : j'ai un peu du mal a tout comprendre ce que fait cette reg exp.
    pourquoi un chomp ligne 8 ? enleve le retour chariot qui est eventuellement à la fin de la chaine ?
    l'appel de la fonction avec le $_ fait quoi exactement ?
    my $ligne = shift ça veut dire ? retourne la première valeur d'un array ?
    etc...

    2) Aussi, imagine que mon fichier que je dois traiter en entrée fait 500 000 lignes, est ce que ce code sera fonctionnel ?

    3) J'ai vu que ça fonctionne si mon couple de guillemets est sur plus de 2 lignes, par exemple 3,4,5 lignes. C'est grâce à l'appel recursif ?
    Idem si j'ai 2,3,4,5, etc.. couples de guillemets sur la même ligne ?

    J'espère ne pas trop abusé de ta gentillesse.

    Merci énormément encore du temps que tu m'as consacré.

    et bonne journée

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Nettoyer les \n entres des guillemets
    Par rambc dans le forum Général Python
    Réponses: 6
    Dernier message: 11/07/2013, 15h05
  2. Rechercher un string entre des guillemets (Expression régulière)
    Par misswatson dans le forum Débuter avec Java
    Réponses: 27
    Dernier message: 22/04/2013, 15h55
  3. Réponses: 2
    Dernier message: 11/01/2012, 00h28
  4. Récupérer valeur entre des balises script
    Par lirycs78 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 26/10/2010, 15h07
  5. [C# 1.1] Comment récupérer du texte entre des mots connus ?
    Par foolsky dans le forum Windows Mobile
    Réponses: 8
    Dernier message: 26/04/2006, 15h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo