Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2443 connectés 

  FORUM HardWare.fr
  Programmation
  Perl

  reconnaissance de plusieurs mots sur une même ligne

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

reconnaissance de plusieurs mots sur une même ligne

n°1874686
lucie 25
Posté le 18-04-2009 à 14:56:13  profilanswer
 

bonjour,
connaîtriez-vous la façon dont on peut faire lire une ligne entière à perl?
j'ai éclusé toutes mes ressources internet et sur papier, je ne trouve pas de solution.
ils parlent souvent du fait que perl cherche toujours l'expression rationnelle le plus tôt possible dans la chaîne, mais nulle part ils ne disent comment contrecarrer ce phénomène.
si vous pouviez m'éclairer un peu, je vous en serai reconnaissante.
de plus sauriez-vous comment on peut faire lire plusieurs textes à la suite pour un même programme??
à l'avance merci


Message édité par lucie 25 le 18-04-2009 à 14:57:19
mood
Publicité
Posté le 18-04-2009 à 14:56:13  profilanswer
 

n°1876593
gilou
Modérateur
Modzilla
Posté le 23-04-2009 à 02:02:44  profilanswer
 

Si vous pouviez être plus claire dans ce que vous cherchez a faire, ca nous permettrait de repondre, parce que la...
 
> lire une ligne entière à perl
perl, ca execute des scripts, alors ce n'est pas tres clair. Faire lire une ligne entiere a un script? Une ligne qui vient d'ou?  
 
> ils parlent souvent du fait que perl cherche toujours l'expression rationnelle le plus tôt possible dans la chaîne, mais nulle part ils ne disent comment contrecarrer ce phénomène.  
Expression rationelle?? vous voulez dire expression réguliere je suppose. Au contraire perl cherche le plus grand texte matchant une expression régulière. Mais il y a moyen de lui faire chercher le plus petit texte matchant une expression régulière, c'est dans la doc perl pour les expressions régulieres (on y remplace * par *?, + par +? et ? par ??)
 
>> de plus sauriez-vous comment on peut faire lire plusieurs textes à la suite pour un même programme??  
Tout dépend de comment votre script perl lit un texte.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°1876595
lucie 25
Posté le 23-04-2009 à 03:32:55  profilanswer
 

alors en fait j'ai un texte qui est lu par perl ligne par ligne, jusque là aucun problème.
ensuite, je fais reconnaitre des scripts dans mon texte. mon problème est que sur une même ligne écrite lorsque perl me reconnait un script si un autre est présent sur cette même ligne, il ne le reconnaitra pas car il va directement à la ligne suivante... et je voudrai éviter cela.
alors, comment faire???
merci

n°1876607
gilou
Modérateur
Modzilla
Posté le 23-04-2009 à 08:37:03  profilanswer
 

lucie 25 a écrit :

alors en fait j'ai un texte qui est lu par perl ligne par ligne, jusque là aucun problème.
ensuite, je fais reconnaitre des scripts dans mon texte. mon problème est que sur une même ligne écrite lorsque perl me reconnait un script si un autre est présent sur cette même ligne, il ne le reconnaitra pas car il va directement à la ligne suivante... et je voudrai éviter cela.
alors, comment faire???
merci

Je suis désolé, mais ce que vous avez écrit ici ne veut rien dire du tout.

Citation :

j'ai un texte qui est lu par perl ligne par ligne


?? Vous avez un texte lu par un script perl? (car je vous le rappelle, perl n'est qu'un moteur a script, ce qui fait le boulot, comme par exemple de lire une ligne, c'est le script).
Ce script est dans un fichier? alors pourquoi ne pas nous le montrer ici? et si c'est juste une ligne de commande, pourquoi ne pas nous la recopier ici?
 
Le texte lu ligne par ligne, il est dans un fichier je suppose. Comment le script y accède t'il? le nom du fichier est sur la ligne de commande? ou bien le nom du fichier est écrit dans le script perl?

Citation :


ensuite, je fais reconnaitre des scripts dans mon texte.

 
Je suppose qu'ici, vous voulez dire je fais reconnaitre des suites de lettres vérifiant une expression régulière dans mon texte.

Citation :


mon problème est que sur une même ligne écrite lorsque perl me reconnait un script si un autre est présent sur cette même ligne, il ne le reconnaitra pas


Il faut le code de l'expression régulière au minimum ici, pour savoir comment la modifier.
 
A+,
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°1876735
lucie 25
Posté le 23-04-2009 à 13:13:25  profilanswer
 

mon vocabulaire laisse à désirer mais c'est bien ce que vous avez dit.
voici donc mon script à exécuter par perl :
 
open(FICH,"texte19moutons.txt" ) || die "Impossible d'ouvrir le fichier.";
$cpt = 0;
while(<FICH> )
{
$a = $_;
if(/\bmoutons?\b/)
 {
 $cpt = $cpt+1;
 }
}
print "'moutons' existe dans le fichier.\n";
print "J'ai trouve $cpt occurrences de 'moutons'.\n";
close (FICH);
 
portant sur ce texte :  
 
les moutons sont méchants.
les moutons sont des moutons blancs.
les moutons noirs ne sont pas des moutons blancs.
 
Ce texte est sur un fichier séparé du script, dans le dossier bin de perl.
lorsque j'exécute mon script sous commande ms-dos sont reconnues trois des cinq occurrences de "moutons" dans mon texte. et j'ai lu que c'est parce que la reconnaissance d'expressions rationnelles se fait toujours au plus tôt et après le script passe à la ligne suivante. je voudrai donc pouvoir éviter cela et pouvoir compter toutes les occurrences présentes dans mon texte.
merci

n°1876744
couak
Posté le 23-04-2009 à 13:32:08  profilanswer
 

Code :
  1. open(FICH,"test.txt" ) || die "Impossible d'ouvrir le fichier.";
  2. $cpt = 0;
  3. while(<FICH> )
  4. {
  5.     $a = $_;
  6.     while ($a=~/moutons/g)
  7.     {
  8.         $cpt = $cpt+1;
  9.     }
  10. }
  11.  
  12. print "cpt = $cpt\n";

n°1876751
lucie 25
Posté le 23-04-2009 à 13:48:05  profilanswer
 

merci, votre solution fonctionne très bien.
cependant, pour une recherche de thème dans un texte, je dois tenir compte de plusieurs possibilités, et il me semble que cela ne puisse fonctionner avec while... :

Code :
  1. open(FICH_A,"dossier_part01.txt" ) || die "Impossible d'ouvrir le fichier.";
  2.     while(<FICH_A> )
  3.     {
  4.         @a = @_;
  5.         if($religion =~/\bdieu\b/i||/\bfoi\b/i||/\bprofane\b/i||/\bprieres?\b/i||/\bames?\b/i||/\banges?\b/i||/\bcroire\b/i||/\beglises?\b/i||/\bcloches?\b/i||/\bciel\b/i)
  6.         {
  7.             print "Le theme de la religion est present dans le fichier.\n";
  8.         }
  9.         elsif($violence =~ /\bviole?\b/i||/\bsouffrir\b/i||/\bpoings?\b/i||/\bcoups?\b/i||/\bdrames?\b/i||/\blames?\b/i||/\bcanons?\b/i||/\btirer\b/i||/\bfureur\b/)
  10.         {
  11.             print "Le theme de la violence est present dans le fichier.\n";
  12.         }
  13.         elsif($tristesse =~ /\bpeine\b/i||/\bpleure?s?\b/i||/\btriste\b/i||/\blarmes?\b/i||/\bchagrins?\b/i||/\bsanglots?\b/i||/\bdrame\b/i)
  14.         {
  15.             print "Le theme de la tristesse est present dans le fichier.\n";
  16.         }
  17.         elsif($amour =~ /\bamours?eux?\b/i||/\baimer?ent?\b/i||/\bbaisers\b/i||/\b(mon|ton) autre\b/i||/\bcoeurs?\b/i||/\btendre\b/i||/\bcaresses?\b/i)
  18.         {
  19.             print "Le theme de l'amour est present dans le fichier.\n";
  20.         }
  21.         elsif($vie =~ /\bnaitre\b/i||/\bmourir\b/i||/\bmort\b/i||/\bvies?\b/i||/\bexister?\b/i||/\bla fin\b/i||/\ben cloque\b/i||/\bgrandir\b/i||/\bvivre\b/i||/\btemps\b/i)
  22.         {
  23.             print "Le theme de la vie est present dans le fichier.\n";
  24.         }
  25.         elsif($joie =~ /\bsourires?\b/i||/\brigoler?\b/i||/\brires?\b/i||/\bbonheur\b/i||/\bjoie\b/i)
  26.         {
  27.                 print "Le theme de la joie est present dans le fichier.\n";
  28.         }
  29.         elsif($hiver =~ /\bnoel\b/i||/\bfroid\b/i||/\bmanteau blanc\b/i||/\bneige\b/i)
  30.         {
  31.             print "Le theme de l'hiver est present dans le fichier.\n";
  32.         }
  33.         else
  34.         {
  35.             print "Il n'y a pas d'autres themes reconnus dans ce fichier.\n";
  36.         }
  37.     }
  38.     close (FICH_A);


merci de votre aide

 

édité par Elmoricq : ajout des balises [code] pour plus de lisibilité


Message édité par Elmoricq le 23-04-2009 à 13:58:27
n°1876770
couak
Posté le 23-04-2009 à 14:24:50  profilanswer
 

tu n'as pas besoin du while si tu n'as pas besoin de compter plus d'une occurence sur la ligne

n°1876772
lucie 25
Posté le 23-04-2009 à 14:26:44  profilanswer
 

et bien justement c'est plus ou moins le même problème que pour compter c'est-à-dire que si j'ai plusieurs mots-clés sur une même ligne, il n'en reconnaitra qu'un seul (le premier)...
et je voudrai éviter cela
merci

n°1876958
couak
Posté le 23-04-2009 à 16:28:55  profilanswer
 

normalement non si ta regex est bien construite
pour faire des OU logique il faut utiliser un seul pipe "|"
et au pire tu peux faire des boucles while au lieu de ton if

mood
Publicité
Posté le 23-04-2009 à 16:28:55  profilanswer
 

n°1876969
lucie 25
Posté le 23-04-2009 à 16:38:25  profilanswer
 

ok  
mais comment puis-je savoir si ma regex est bien construite?? je débute totalement...

n°1877097
gilou
Modérateur
Modzilla
Posté le 24-04-2009 à 04:08:07  profilanswer
 

Une solution parmi d'autres possibles, que j'ai pas mal commenté, puisque tu débutes.

Code :
  1. #!/usr/bin/perl
  2. use warnings;
  3. use strict;
  4.  
  5. #Une liste de fichiers a lire, sous forme d'un array
  6. my @fichiers = ("dossier_part01.txt" );
  7.  
  8. #les themes sous une forme plus facile a saisir:
  9. #Un hash, avec pour cle le nom du theme et valeur un array anonyme
  10. #contenant les mots a chercher pour le theme
  11. my %themes = (
  12.    "la religion"  => ["dieux?", "foi", "profanes?", "prieres?", "ames?",
  13.                       "anges?", "croire", "eglises?", "cloches?", "ciel"],
  14.    "la violence"  => ["viole?s?", "souffrir", "poings?", "coups?", "drames?",
  15.                       "blames?", "canons?", "tirer", "fureurs?"],
  16.    "la tristesse" => ["peines?", "pleure?s?", "tristes?", "larmes?", "chagrins?",
  17.                       "sanglots?", "drames?"],
  18.    "l'amour"      => ["amours?eux?", "aimer?ent?", "baisers?", "(mon|ton) autre", "coeurs?",
  19.                       "tendres?", "caresses?"],
  20.    "la vie"       => ["naitre", "mourir", "mort", "vies?", "exister?",
  21.                       "la fin", "en cloque", "grandir", "vivre", "temps"],
  22.    "la joie"      => ["sourires?", "rigoler?", "rires?", "bonheur", "joie"],
  23.    "l'hiver"      => ["noel", "froid", "manteau blanc", "neige"],
  24.    );
  25.  
  26. #je fabrique par programme un nouveau hash, qui va avoir les memes cles (les noms de themes),
  27. #et pour valeur un array anonyme a deux elements, en premier, un flag initialise a zero
  28. #et en second la chaine expression reguliere correspondant au theme
  29. my %recherche;
  30. foreach my $i (keys(%themes)) {
  31.   $recherche{$i} = [0, make_regexp($themes{$i})];
  32. }
  33.  
  34. #en entree, une reference sur un array anonyme de mots, on colle des \b autour des mots,
  35. #puis des | entre, pour fabriquer l'expression reguliere.
  36. sub make_regexp {
  37.    my $liste_mot = shift;
  38.    my $regexp = join '|', map {'\b'.$_.'\b'} @$liste_mot;
  39.    return $regexp;
  40. }
  41.  
  42. foreach my $fichier (@fichiers) {
  43.    open(FICH_A, $fichier)
  44.        || (print "Impossible d'ouvrir le fichier $fichier.\n" and next);
  45.    while (<FICH_A> ) {
  46.        foreach my $i (keys(%themes)) { #pour chaque expression reguliere
  47.            unless ($recherche{$i}->[0]) { #si on n'a pas déja trouvé une ligne qui colle
  48.                if (/$recherche{$i}->[1]/i) { #on cherche l'expression dans la ligne en cours du fichier
  49.                    ++$recherche{$i}->[0]; #si trouvé, on positionne le flag
  50.                }
  51.            }
  52.        }
  53.    }
  54.    close (FICH_A);
  55.  
  56.    my $found = 0; #un flag global qui va indiquer si au moins un theme a ete trouve
  57.    foreach my $i (keys(%themes)) { #on boucle sur les themes
  58.        if ($recherche{$i}->[0]) { #si le flag est mis
  59.            print "Le theme de ", $i, " est present dans le fichier $fichier.\n";
  60.            ++$found;
  61.            #remise a zero du flag pour la recherche sur le fichier suivant.
  62.            $recherche{$i}->[0] = 0;
  63.        }
  64.    }
  65.    if ($found) {
  66.        print "Il n'y a pas d'autres themes reconnus dans le fichier $fichier.\n";
  67.    }
  68.    else {
  69.        print "Il n'y a pas de themes reconnus dans le fichier $fichier.\n";
  70.    }
  71. }
  72.  


A+,


Message édité par gilou le 24-04-2009 à 04:11:07

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°1880865
lucie 25
Posté le 04-05-2009 à 23:32:52  profilanswer
 

je te remercie pour ton aide!! malheureusement, cela ne convient pas...
mon but est un peu complexe... mais merci quand même

n°1881201
gilou
Modérateur
Modzilla
Posté le 05-05-2009 à 20:35:25  profilanswer
 

Et si au lieu de nous dire que ça ne te convient pas, tu nous expliquais ce qui te conviendrait. Ou pourquoi cela ne te convient pas...
Ce serait peut être plus constructif.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°1881213
lucie 25
Posté le 05-05-2009 à 21:50:36  profilanswer
 

Alors, pour faire simple, mon prof me demande de faire un projet me permettant d'extraire un thème de chaque texte présenté et de faire un résumé automatique de chacun de ces textes. Je me suis restreinte à 11 textes portant sur 5 thèmes.
J'ai donc écrit un script qui permet de faire demander en premier lieu sur quel texte on veut travailler et par la suite faire ouvrir le texte en question il s'agit de mon script principal.  
Ensuite, j'ai écrit un sous programme permettant de faire reconnaître mes expressions régulières associées à chacun de mes thèmes. Cependant dans un même texte, plusieurs thèmes peuvent être présent, et j'ai tenté de mettre en place un compteur qui pourrait me permettre d'évaluer la fréquence d'expressions régulières la plus important et ainsi n'en ressortir qu'un seul thème (ce qui, au passage, n'a aboutit) avec un deuxième sous-dossier.  
Et pour le moment je n'ai pas osé tenter le résumé automatique.
Voici mon programme :  
 

Code :
  1. #!/user/perl/bin
  2.  
  3. print "\n";
  4. print "Entrez le numero du texte a analyser (de 1 a 11) : ";
  5. chop($z = <STDIN> );
  6. print "\n";
  7. sub theme
  8. {
  9.     @a = @_;
  10.     $cptA = 0;
  11.     $cptB = 0;
  12.     $cptC = 0;
  13.     $cptD = 0;
  14.     $cptE = 0;
  15.     if($tsunami =~/\bdéferlante\b/i|/\bvagues?\b/i|/\braz-de-marée\b/i|/\btsunami\b/i|/\bcôtes?\b/i|/\bondes?\b/i)
  16.     {
  17.         $cptA = $cptA + 1;
  18.         print "Le theme des tsunamis est present dans le fichier.\n";
  19.     }
  20.     elsif($seisme =~ /\bsecousses?\b/i|/\béchelle de msk\b/i|/\béchelle de richter\b/i|/\bépicentres?\b/i|/\bséismes?\b/i|/\bmagnitude\b/i|/\bhypocentres?\b/i|/\btremblement de terre\b/i|/\bfailles?\b/i|/\btectonique\b/i|/\bplaques?\b/i|/\bcollisions?\b/i)
  21.     {
  22.         $cptB = $cptB + 1;
  23.         print "Le theme des seismes est present dans le fichier.\n";
  24.     }
  25.     elsif($volcan =~ /\béruptions?\b/i|/\bnuées? ardentes?\b/i|/\bcendres?\b/i|/\bvolcans?\b/i|/\bmagma\b/i|/\btendre\b/i|/\bfumées?\b/i|/\bpoussières?\b/i|/\blave\b/i|/\bcoulées\b/i|/\bvolcanique\b/i)
  26.     {
  27.         $cptC = $cptC + 1;
  28.         print "Le theme des volcans est present dans le fichier.\n";
  29.     }
  30.     elsif($cyclone =~ /\bcyclones?\b/i|/\bdépression\b/i|/\bouragans?\b/i|/\btyphons?\b/i|/\bpluies torrentielles\b/i|/\bvents violents\b/i|/\bfortes inondations\b/i|/\bnuages?\b/i)
  31.     {
  32.         $cptD = $cptD + 1;
  33.         print "Le theme des cyclones est present dans le fichier.\n";
  34.     }
  35.     elsif($inondation =~ /\binondations?\b/i|/\bcrues?\b/i|/\bsubmergé?e?s?a?n?t?\b/i|/\bdébordements?\b/i|/\béchelle hydrométrique\b/i|/\bmontée des eaux\b/i)
  36.     {
  37.         $cptE = $cptE + 1;
  38.         print "Le theme des inondations est present dans le fichier.\n";
  39.     }
  40.     else
  41.     {
  42.         print "Il n'y a pas d'autres themes reconnus dans ce fichier.\n";
  43.     }
  44. }
  45.  
  46. sub theme02
  47. {
  48.     if($cptA > $cptB & $cptA > $cptC & $cptA > $cptD & $cptA > $cptE)
  49.     {
  50.         print "Le texte parle de tsunami.\n";
  51.     }
  52.     elsif($cptB > $cptA & $cptB > $cptC & $cptB > $cptD & $cptB > $cptE)
  53.     {
  54.         print "Le texte parle de seisme.\n";
  55.     }
  56.     elsif($cptC > $cptA & $cptC > $cptB & $cptC > $cptD & $cptC > $cptE)
  57.     {
  58.         print "Le texte parle d'eruption volcanique.\n";
  59.     }
  60.     elsif($cptD > $cptA & $cptD > $cptB & $cptD > $cptC & $cptD > $cptE)
  61.     {
  62.         print "Le texte parle de cyclone.\n";
  63.     }
  64.     elsif($cptE > $cptA & $cptE > $cptB & $cptE > $cptC & $cptE > $cptD)
  65.     {
  66.         print "Le texte parle d'inondation.\n";
  67.     }
  68.     else
  69.     {
  70.         print "Il n'y a pas de theme traité ici.\n";
  71.     }
  72. }
  73.  
  74. if($z == 1)
  75. {
  76.     open(FICH01,"texte01.txt" ) || die "Impossible d'ouvrir le fichier.";
  77.     while(<FICH01> )
  78.     {
  79.         theme;
  80.     }
  81.     close (FICH01);
  82.     
  83. }
  84. elsif($z == 2)
  85. {
  86.     open(FICH02,"texte02.txt" ) || die "Impossible d'ouvrir le fichier.";
  87.     while(<FICH02> )
  88.     {
  89.         theme;
  90.     }
  91.     close (FICH02);
  92. }
  93. elsif($z == 3)
  94. {
  95.     open(FICH03,"texte03.txt" ) || die "Impossible d'ouvrir le fichier.";
  96.     while(<FICH03> )
  97.     {
  98.         theme;
  99.     }
  100.     close (FICH03);
  101. }
  102. elsif($z == 4)
  103. {
  104.     open(FICH04,"texte04.txt" ) || die "Impossible d'ouvrir le fichier.";
  105.     while(<FICH04> )
  106.     {
  107.         
  108.         theme;
  109.     }
  110.     close (FICH04);
  111. }
  112. elsif($z == 5)
  113. {
  114.     open(FICH05,"texte05.txt" ) || die "Impossible d'ouvrir le fichier.";
  115.     while(<FICH05> )
  116.     {
  117.         theme;
  118.     }
  119.     close (FICH05);
  120. }
  121. elsif($z == 6)
  122. {
  123.     open(FICH06,"texte06.txt" ) || die "Impossible d'ouvrir le fichier.";
  124.     while(<FICH06> )
  125.     {
  126.         theme;
  127.     }
  128.     close (FICH06);
  129. }
  130. elsif($z == 7)
  131. {
  132.     open(FICH07,"texte07.txt" ) || die "Impossible d'ouvrir le fichier.";
  133.     while(<FICH07> )
  134.     {
  135.         theme;
  136.     }
  137.     close (FICH07);
  138. }
  139. elsif($z == 8)
  140. {
  141.     open(FICH08,"texte08.txt" ) || die "Impossible d'ouvrir le fichier.";
  142.     while(<FICH08> )
  143.     {
  144.         theme;
  145.     }
  146.     close (FICH08);
  147. }
  148. elsif($z == 9)
  149. {
  150.     open(FICH09,"texte09.txt" ) || die "Impossible d'ouvrir le fichier.";
  151.     while(<FICH09> )
  152.     {
  153.         theme;
  154.     }
  155.     close (FICH09);
  156. }
  157. elsif($z == 10)
  158. {
  159.     open(FICH10,"texte10.txt" ) || die "Impossible d'ouvrir le fichier.";
  160.     while(<FICH18> )
  161.     {
  162.         theme;
  163.     }
  164.     close (FICH10);
  165. }
  166. elsif($z == 11)
  167. {
  168.     open(FICH11,"texte11.txt" ) || die "Impossible d'ouvrir le fichier.";
  169.     while(<FICH11> )
  170.     {
  171.         theme;
  172.     }
  173.     close (FICH11);
  174. }
  175. else
  176. {
  177.     print "Vous n'avez pas selectionne un nombre compris entre 1 et 22!\n";
  178. }


 
Le second sous programme n'est pas mis pour être effectué car je ne veux pas qu'il tourne en boucle en l'incluant dans la boucle while, cependant ailleurs il ne fonctionne pas du tout...
Je pense que je me suis compliqué les choses mais je ne vois malheureusement pas comment me simplifier...
merci quand même


Message édité par gilou le 06-05-2009 à 16:20:04
n°1881576
gilou
Modérateur
Modzilla
Posté le 06-05-2009 à 18:01:40  profilanswer
 

Bon, déja, on peut simplifier tout ce qui se passe en dehors de la routine theme:
 

Code :
  1. #!/usr/bin/perl
  2.  
  3. use warnings;
  4. use strict;
  5.  
  6. # le programme principal
  7. my $numero = numero_texte(); #on recupere le numero, ou bien on quitte le programme
  8. my $filename = sprintf("texte%02d.txt", $numero); #on fabrique le nom du fichier
  9. open(FICHIER, "<", $filename) || die "Impossible d'ouvrir le fichier $filename";
  10. while(<FICHIER> )
  11. {
  12.    theme();
  13. }
  14. close(FICHIER);
  15.  
  16. # les subroutines
  17.  
  18. # recupere le numero, ou bien on quitte le programme
  19. # appel: numero_texte()
  20. # retour: le numero (si on n'a pas quitte le programme)
  21. sub numero_texte {
  22.    my $numero;
  23.    while (1) { # boucle infinie
  24.        print STDOUT "Entrez le numero du texte a analyser (de 1 a 11): ";
  25.        if (valider_entree("0*([1-9]||1[0-1])", \$numero)) {
  26.            return $numero;
  27.        } else {
  28.            print STDOUT "Le numero entre n'est pas valide.\n";
  29.            print STDOUT "Voulez vous recommencer? ";
  30.            unless (valider_simple("O(ui)?" )) {
  31.                exit;
  32.            }
  33.        }
  34.    }
  35. }
  36.  
  37. # valide l'entree utilisateur par rapport a un pattern
  38. # et recupere la valeur validee
  39. # appel: valider_entree($pattern, \$entree)
  40. # retour: 0 si entree non validee, 1 si validee, et en ce cas
  41. # $entree contient la valeur validee
  42. sub valider_entree {
  43.    my $pattern = shift;
  44.    my $entree  = shift;
  45.    $| = 1;
  46.    my $reponse = <STDIN>;
  47.    clean($reponse);
  48.    $$entree = $reponse;
  49.    return ($reponse && $reponse =~ /^$pattern$/i);
  50. }
  51.  
  52. # valide l'entree utilisateur par rapport a un pattern
  53. # appel: valider_entree($pattern)
  54. # retour: 0 si entree non validee, 1 si validee
  55. sub valider_simple {
  56.    my $pattern = shift;
  57.    $| = 1;
  58.    my $reponse = <STDIN>;
  59.    clean($reponse);
  60.    return ($reponse && $reponse =~ /^$pattern$/i);
  61. }
  62.  
  63. sub clean {
  64.    $_[0]=~ s/^\s+//;
  65.    $_[0]=~ s/\s+$//;
  66. }
  67.  
  68. sub theme {
  69.    # a implementer
  70. }


 
En particulier, quand on a des routines avec une entrée utilisateur, mieux vaut les traiter a part, afin de boucler tant que l'entrée n'est pas correcte, etc.
Plutôt que de coder en dur 11 cas différents pour vos noms de fichier, il était plus simple de construire le nom du fichier à partir du numéro et d'utiliser un code commun.
 
A+,
 
 
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°1881652
gilou
Modérateur
Modzilla
Posté le 06-05-2009 à 23:07:22  profilanswer
 

Bon, j'ai regardé la suite du pb.
Voici un exemple que tu peux adapter en fonction de tes besoins. J'ai gardé les thèmes de la précédente fois.
 

Code :
  1. #!/usr/bin/perl
  2.  
  3. use warnings;
  4. use strict;
  5.  
  6. #les themes sous une forme plus facile a saisir:
  7. # Un hash, avec pour cle le nom du theme et valeur un array anonyme
  8. # contenant les mots a chercher pour le theme
  9. my %themes = (
  10.    "la religion"  => ["dieux?", "foi", "profanes?", "prieres?", "ames?",
  11.                       "anges?", "croire", "eglises?", "cloches?", "ciel"],
  12.    "la violence"  => ["viole?s?", "souffrir", "poings?", "coups?", "drames?",
  13.                       "blames?", "canons?", "tirer", "fureurs?"],
  14.    "la tristesse" => ["peines?", "pleure?s?", "tristes?", "larmes?", "chagrins?",
  15.                       "sanglots?", "drames?"],
  16.    "l'amour"      => ["amours?(eux)?", "aimer?(ent)?", "baisers?", "(mon|ton) autre", "coeurs?",
  17.                       "tendres?", "caresses?"],
  18.    "la vie"       => ["naitre", "mourir", "mort", "vies?", "exister?",
  19.                       "la fin", "en cloque", "grandir", "vivre", "temps"],
  20.    "la joie"      => ["sourires?", "rigoler?", "rires?", "bonheur", "joie"],
  21.    "l'hiver"      => ["noel", "froid", "manteau blanc", "neige"],
  22.    );
  23.  
  24. # je fabrique par programme un nouveau hash, qui va avoir les memes cles (les noms de themes),
  25. # et pour valeur un array anonyme a trois elements, en premier, un compteur du nombre d'occurences
  26. # en second un compteur de lignes ou le theme apparait
  27. # et en troisieme la chaine expression reguliere correspondant au theme
  28. my %recherche;
  29. foreach my $i (keys(%themes)) {
  30.   $recherche{$i} = [0, 0, make_regexp($themes{$i})];
  31. }
  32.  
  33.  
  34. # le programme principal
  35. my $numero = numero_texte(); #on recupere le numero, ou bien on quitte le programme
  36. my $filename = sprintf("texte%02d.txt", $numero);
  37. open(FICHIER, "<", $filename) || die "Impossible d'ouvrir le fichier $filename";
  38. while (<FICHIER> ) {
  39.    foreach my $i (keys(%themes)) { #pour chaque expression reguliere
  40.        #on cherche l'expression dans la ligne en cours du fichier
  41.        if (/$recherche{$i}->[2]/i) {
  42.            ++$recherche{$i}->[1]; # et on incremente le compteur de lignes ou il y a occurence
  43.            while (/$recherche{$i}->[2]/gi)
  44.                {
  45.                    ++$recherche{$i}->[0]; # et on incremente le compteur d'occurence
  46.                }
  47.        }
  48.    }
  49. }
  50. close(FICHIER);
  51.  
  52. my $found = 0; #un flag global qui va indiquer si au moins un theme a ete trouve
  53. foreach my $i (keys_by_occurences(\%themes)) { #on boucle sur les themes
  54.    if ($recherche{$i}->[0]) { #si le compteur n'et pas à zero
  55.        if ($recherche{$i}->[1] > 1) {
  56.            print "Le theme de ", $i, " est present $recherche{$i}->[0] fois ",
  57.                "dans $recherche{$i}->[1] lignes du fichier $filename.\n";
  58.        }
  59.        else {
  60.            print "Le theme de ", $i, " est present $recherche{$i}->[0] fois ",
  61.                "dans 1 ligne du fichier $filename.\n";
  62.        }
  63.        ++$found;
  64.    }
  65. }
  66. if ($found) {
  67.    print "Il n'y a pas d'autres themes reconnus dans le fichier $filename.\n";
  68. }
  69. else {
  70.    print "Il n'y a pas de themes reconnus dans le fichier $filename.\n";
  71. }
  72.  
  73.  
  74. # les subroutines
  75.  
  76. # recupere le numero, ou bien on quitte le programme
  77. # appel: numero_texte()
  78. # retour: le numero (si on n'a pas quitte le programme)
  79. sub numero_texte {
  80.    my $numero;
  81.    while (1) { # boucle infinie
  82.        print STDOUT "Entrez le numero du texte a analyser (de 1 a 11): ";
  83.        if (valider_entree("0*([1-9]||1[0-1])", \$numero)) {
  84.            return $numero;
  85.        } else {
  86.            print STDOUT "Le numero entre n'est pas valide.\n",
  87.                "Voulez vous recommencer? ";
  88.            exit unless (valider_simple("O(ui)?" ));
  89.        }
  90.    }
  91. }
  92.  
  93. # valide l'entree utilisateur par rapport a un pattern
  94. # et recupere la valeur validee
  95. # appel: valider_entree($pattern, \$entree)
  96. # retour: 0 si entree non validee, 1 si validee, et en ce cas
  97. # $entree contient la valeur validee
  98. sub valider_entree {
  99.    my $pattern = shift;
  100.    my $entree  = shift;
  101.    $| = 1;
  102.    my $reponse = <STDIN>;
  103.    clean($reponse);
  104.    $$entree = $reponse;
  105.    return ($reponse && $reponse =~ /^$pattern$/i);
  106. }
  107.  
  108. # valide l'entree utilisateur par rapport a un pattern
  109. # appel: valider_entree($pattern)
  110. # retour: 0 si entree non validee, 1 si validee
  111. sub valider_simple {
  112.    my $pattern = shift;
  113.    $| = 1;
  114.    my $reponse = <STDIN>;
  115.    clean($reponse);
  116.    return ($reponse && $reponse =~ /^$pattern$/i);
  117. }
  118.  
  119. sub clean {
  120.    $_[0]=~ s/^\s+//;
  121.    $_[0]=~ s/\s+$//;
  122. }
  123.  
  124. #en entree, une reference sur un array anonyme de mots, on colle des \b autour des mots,
  125. #puis des | entre, pour fabriquer l'expression reguliere.
  126. sub make_regexp {
  127.    my $liste_mot = shift;
  128.    my $regexp = join '|', map {'\b'.$_.'\b'} @$liste_mot;
  129.    return $regexp;
  130. }
  131.  
  132. # en sortie, les cles de %themes ordonnées en fonction du compteur d'occurence du theme
  133. # lequel est le premier champ de recherche et en cas d'égalité du nombre d'occurences
  134. # en fonction du nombre de lignes ou il y a occurences
  135. # voir mon topic sur les astuces en perl pour en comprendre le fonctionnement
  136. sub keys_by_occurences {
  137.    my $array = shift;
  138.    return map $_->[0],
  139.        sort {
  140.            $b->[1] <=> $a->[1]
  141.            or
  142.            $b->[2] <=> $a->[2]
  143.        }
  144.            map [$_, $recherche{$_}->[0], $recherche{$_}->[1]], keys(%$array);
  145. }


 
A+,


Message édité par gilou le 06-05-2009 à 23:18:10

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°1881659
lucie 25
Posté le 07-05-2009 à 00:03:54  profilanswer
 

merci beaucoup, je vais essayer de me faire avec tout ça (bien que par moment je ne comprenne pas tout...)
encore merci
à plus


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Perl

  reconnaissance de plusieurs mots sur une même ligne

 

Sujets relatifs
[Réglé](Regex) Récupération d'une chaîne située entre deux motsRecuperer ligne de fichier dans variables séparées
Supprimer plusieurs lignes dans une sélectionne conserver que la dernière ligne d' un fichier texte
Plusieurs comptes à rebours sur la même page htmlScript Performant de Densité de mots clefs
Densité des mots clefs & OccurencesOCR (reconnaissance texte dans image) + coordonnées X, Y
[Résolu] Edit mono-ligne avec retour à la ligne ?tri de plusieurs tableau
Plus de sujets relatifs à : reconnaissance de plusieurs mots sur une même ligne


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR