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

  FORUM HardWare.fr
  Programmation
  Perl

  Extraire un mot d'une ligne suivant ce qui l'encadre

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Extraire un mot d'une ligne suivant ce qui l'encadre

n°2081601
le fou
Forza Massallia
Posté le 09-06-2011 à 16:08:19  profilanswer
 

Bonjour,
 
je développe un petit script en perl (pour l'utilité et aussi pour apprendre), et j'ai besoin d'extraire un mot d'une ligne.
En fait je lit un fichier ligne par ligne.
 
Exemple de fichier
bla
bla
bla.all
all blabla
retour ALL;
ball
return all return;
 
Donc, je cherche a extraire des lignes le mot "all" seulement (sans distinction de casse). Il peut être encadré par :
des espaces
des tabulation
une fin de ligne
un début de ligne
un point (.)
un point virgule (;)
 
mais rien d'autres.
 
Je suis arrivé (mais sans grand résultat) à l'expression suivante :

Code :
  1. /[\s.]*all[\s;]/i


 
mais je n'obtiens pas la ligne 3 ("bla.all" )
 
merci de vos réponses.


---------------
Celui qui sauve une vie, sauve l'humanité (Le Talmud) - Personne n'a plus grand amour que celui de donner sa vie pour ses amis (Jean XV, 13)
mood
Publicité
Posté le 09-06-2011 à 16:08:19  profilanswer
 

n°2081674
gilou
Modérateur
Modzilla
Posté le 09-06-2011 à 19:26:18  profilanswer
 

/(^|[\s\t.;])all([\s\t.;]|$)/oi
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2081695
le fou
Forza Massallia
Posté le 09-06-2011 à 21:28:40  profilanswer
 

Ah oui forcement, j'étais mal parti.
D'abord merci beaucoup.

 

Puis, je connais le i, que signifie le 'o' aprés le dernier / ?

 

Je dis peut être une ânerie mais \t n'est pas compris dans \s?


Message édité par le fou le 09-06-2011 à 21:30:09

---------------
Celui qui sauve une vie, sauve l'humanité (Le Talmud) - Personne n'a plus grand amour que celui de donner sa vie pour ses amis (Jean XV, 13)
n°2081787
gilou
Modérateur
Modzilla
Posté le 10-06-2011 à 11:01:05  profilanswer
 

Citation :

Je dis peut être une ânerie mais \t n'est pas compris dans \s?

Tout a fait, j'ai tapé sans me relire (juste fait un test rapide avec un script).
C'est /(^|[ \t.;])all([ \t.;]|$)/oi qui correspond exactement à tes specs. Ou bien /(^|[\s.;])all([\s.;]|$)/oi si la notion d'espace de ta spec ne désigne pas que le blanc..

Citation :

Puis, je connais le i, que signifie le 'o' aprés le dernier / ?

o = once: on ne compile qu'une fois l'expression, car rien a l'intérieur ne va changer à chaque pattern matching. C'est une optimisation et une bonne habitude à prendre.
A+,
 
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2081814
le fou
Forza Massallia
Posté le 10-06-2011 à 11:33:01  profilanswer
 

Merci beaucoup Gilou pour tes explications.
 
Tu as raison, j'avais oublié de spécifier ce que j'entendais par blanc (espaces et/ou tab)
 
Euh, excuses moi, j'ai encore une question :
 
Dans l'absolut je voudrais utiliser cette expression pour recherche plusieurs mots. C'est à dire j'ai une liste de mots, et je voudrais faire cette recherhe avec chaque mots de la liste.
 
J'ai donc :
 

Code :
  1. my @liste  = ("all", "wait", "abs" );
  2. foreach $item (@liste)
  3. {
  4.     if ( //(^|[\s.;])$item([\s.;]|$)/oi )
  5.     {
  6.         print "mot trouve\n";
  7.     }
  8.     else
  9.     {
  10.         print "mot non trouve\n";       
  11.     }
  12. }


 
Cependant, il ne prend pas $item comme étant une variable mais la chaine à chercher. Comme lui faire comprendre l'inverse?
 
Ps : j'imagine que dans ce cas, l'option o n'est plus utile puisque l'expression va changer suivant le mot. J'ai bon?


---------------
Celui qui sauve une vie, sauve l'humanité (Le Talmud) - Personne n'a plus grand amour que celui de donner sa vie pour ses amis (Jean XV, 13)
n°2081896
le fou
Forza Massallia
Posté le 10-06-2011 à 17:54:54  profilanswer
 

Bon je me réponds tout seul.
Je suis un âne, bien que tu m'es expliqué que l'opérateur o  ne signifiait qu'il ne compilait l'expression qu'une fois. Or si je change la variable dedans ca risque de pas marcher.
 
Merci.


---------------
Celui qui sauve une vie, sauve l'humanité (Le Talmud) - Personne n'a plus grand amour que celui de donner sa vie pour ses amis (Jean XV, 13)
n°2081897
gilou
Modérateur
Modzilla
Posté le 10-06-2011 à 18:01:48  profilanswer
 

Tout à fait.
Notes que si tu utilises l'option strict (use Strict;) qui est recommandée, il vaudrait mieux écrire:
foreach my $item (@liste)
et d'autre part, pour //(^|[\s.;])$item([\s.;]|$)/oi il y aurait pas un / en trop au début?
 
A+,


Message édité par gilou le 10-06-2011 à 18:02:08

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2081901
gilou
Modérateur
Modzilla
Posté le 10-06-2011 à 19:07:12  profilanswer
 

Pour trouver les mots d'une liste dans un texte donné, voici un exemple, pas nécessairement le plus optimal.

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. use Tie::File;
  6.  
  7. my @testitems = qw(all wait abs return);  # les mots a trouver
  8. my $filename = 'texttest.txt'; # le texte
  9. my %result; # un hash, qui va en sortie contenir pour chaque mot de la liste, le de lignes le contenant
  10.  
  11. tie my @array, 'Tie::File', $filename or die "$!\n"; # pour utiliser un fichier comme un array
  12. foreach my $item (@testitems) {
  13.  $result{$item} = grep {/(^|[\s.;])$item([\s.;]|$)/i} @array; #construction du hash
  14. }
  15. untie @array;
  16.  
  17. print "items found: ";
  18. foreach my $item (@testitems) {
  19.  print "$item " if ($result{$item});
  20. }
  21. print "\n";


#construction du hash:  
grep {/(^|[\s.;])$item([\s.;]|$)/i} @array; retourne une liste des lignes de array ou l'expression régulière donnée est trouvée
comme on est dans un contexte scalaire, $result{$item} = va avoir pour effet d'assigner le nb d'éléments de cette liste à $result{$item}, et donc 0 si $item n'a pas été trouvé.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2082334
le fou
Forza Massallia
Posté le 14-06-2011 à 13:37:50  profilanswer
 

Salut Gilou,
 
Merci pour tes réponses.
 
En fait, je me suis mal exprimé dés le début, ce que je voudrais en réalité, c'est afficher les lignes ou au moins l'un des ces mots clés n'est pas en majuscules.
 
 


---------------
Celui qui sauve une vie, sauve l'humanité (Le Talmud) - Personne n'a plus grand amour que celui de donner sa vie pour ses amis (Jean XV, 13)
n°2082419
gilou
Modérateur
Modzilla
Posté le 14-06-2011 à 20:18:53  profilanswer
 

Un truc comme ça alors:

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. my @testlist = ("Alias Toto", "alias TUTU TOTO", "TOTO ALIAS", "AlIAS TOTO", "TUTU haha" ); # pour tester
  6. my @words = qw(alias toto tutu); # les mots clés
  7. my $regexp = "(". join('|', map {uc($_)} @words) . " )"; # (ALIAS|TOTO|TUTU) ici
  8.  
  9. foreach my $line (@testlist) {
  10.  local $_ = $line;
  11.  if (/$regexp/io) { # on saute les lignes sans mots clés
  12.    s/(^|\s)$regexp(?=\s|$)//go; # on vire les mots clés en majuscule
  13.    print  "$line\n" if (/$regexp/io); # on imprime la ligne s'il reste un mot clé
  14.  }
  15. }


L'idée: sur les lignes qui ont au moins un mot clé, on vire tous les mots clés en majuscule qui y figurent, et si on y trouve encore un mot clé, c'est qu'il y avait au moins un mot clé qui n'était pas en majuscule.
On pourrait se passer de la ligne 11, i.e. on vire tous les mots clés en majuscule de toute ligne, et si on y trouve encore un mot clé, c'est qu'il y avait au moins un mot clé qui n'était pas en majuscule dans la ligne, mais ça fait traiter inutilement des lignes et n'est pas optimal.
J'ai écrit la partie entre les lignes 9 et 15 pour que ce soit assez optimal (je vois pas trop comment optimaliser plus) et que ça ne modifie pas ce qu'on teste (cas par exemple ou la liste est en fait un fichier lié avec Tie::File).
Note: le blanc qui apparaît avant la parenthèse fermante de la définition de $regexp est un artéfact du code d'affichage du forum.
A+,


Message édité par gilou le 14-06-2011 à 23:05:50

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --

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

  Extraire un mot d'une ligne suivant ce qui l'encadre

 

Sujets relatifs
Carnet d'adresse en ligneConnection à une base Mysql (easyPhp) en Java suivant modele MVC
Supression d'un saut de ligne dans une chaîne de caractèresextraire un champ dans un paquet RTP
comment extraire plusieurs chaine de caracteres d'un fichier ???[AS3] portfolio qui ne fonctionne pas en ligne
Lire une ligne d'un texte à l'aide d'un pointeur[php] Envoyer resultat requete plusieurs ligne par mail
Batch a éxecuter suivant l'adresse ip de la machine ?probleme avec un JAVA suivant le serveur
Plus de sujets relatifs à : Extraire un mot d'une ligne suivant ce qui l'encadre


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