Perl pb pattern matching

Fermé
marge31 Messages postés 3 Date d'inscription lundi 27 juillet 2009 Statut Membre Dernière intervention 28 juillet 2009 - 27 juil. 2009 à 09:51
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 - 29 juil. 2009 à 03:12
Bonjour à tous,

je suis plutôt novice en perl et je rencontre actuellement un problème avec un
programmme de pattern matching.
Mon point de départ est une liste de termes complexes que je dois repérer dans un corpus. Jusque là, pas de souci, mon prog repère les termes. Mais mon but n'est pas de les extraire mais de les baliser dans le corpus lui même et là je sèche.
Si quelqu'un a une idée ce serait super.
Merci d'avance

open (TERMES, "termes.txt") or die "Termes introuvables";

foreach $ligne (<TERMES>){push @termes, $ligne}

foreach(@termes)
{
pluriels($_);
chomp($_);
#s/\r//;
push @termes_plur, $_;
}

@termes_plur = sort{length($b) <=> length($a)} @termes_plur;
#foreach(@termes_plur){print $_."\n"} #Décommenter pour voir les regexps des termes qui seront projetées sur le texte.

open (FICHIER, "corpus.txt") or die "Fichier d'entrée introuvable";

push @fichier, <FICHIER>;

foreach $terme (@termes_plur)
{
foreach(@fichier)
{
while(/($terme)/g){print $terme."\t".$1."\n"}
}
}
A voir également:

6 réponses

lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
27 juil. 2009 à 10:00
Salut,

Ben, je n'ai pas compris ce que tu veux.
Il faudra donner un exemple concret.
Les données en entrée et ce que tu veux obtenir en sortie.

En ce qui concerne ton code il y a des choses redondantes.
@termes contient les lignes de ton fichiers, alors pourquoi stocker dans un tableau, si on peut remplir @termes_plur directement depuis le fichier ?

open (TERMES, "termes.txt") or die "Termes introuvables"; 

while (<TERMES>){ 
{ 
  pluriels($_); # ici je suppose que c'est une fonction écrite par toi
  push @termes_plur, $_; 
} 
chomp(@termes,plur);
0
marge31 Messages postés 3 Date d'inscription lundi 27 juillet 2009 Statut Membre Dernière intervention 28 juillet 2009
27 juil. 2009 à 10:55
Bonjour lami20j,

alors pour être plus claire j'ai au départ une liste de terme que je dois matcher dans un corpus. Ces termes sont du type "manoeuvre de libération". J'applique sur ces termes une fonction "pluriel" qui me permet de matcher également les termes au pluriel . Ce que je veux en sortie, c'est que ces termes soient balisés directement dans le corpus. Ex : blabla <terme>manoeuvre de libération<\terme> blabla

Merci de ton aide
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
27 juil. 2009 à 11:17
Re,

Je n'ai pas testé
open ECRIRE,">>resultat.txt" or die "E/S : $!\n";

while(<FICHIER>){
  foreach my $e(@termes_plur){
    s/(.*)$e(.*)/${1}<balise>${e}</balise>$2/g if /(.*)$e(.*)/;
  }
  print ECRIRE;
}

ou
open ECRIRE,"resultat.txt" or die "E/S : $!\n";

while(<FICHIER>){
  foreach my $e(@termes_plur){
    if (/$e/){
      s/(?=$e)/<balise>/g;
      s/(?<=$e)/<\/balise>/g;
    }
  }
  print ECRIRE;
}
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
27 juil. 2009 à 19:28
Re,

Les script sont en gras.

Et voici le test avec la version 1 de script
(il avait une seule erreur - un backslash dans la chaine de remplacement ;-)
lami20j@debian:~/trash$ cat phrases.txt
ligne 1 toto et titi
ligne 2 tata
ligne 3 rien
titi toto tata
lami20j@debian:~/trash$ cat mots_0.pl
#!/usr/bin/perl
use strict;use warnings;

open FICHIER,"phrases.txt" or die "E/S : $!\n";
open ECRIRE,">>resultat_phrases_0.txt" or die "E/S : $!\n";

my @termes_plur=qw/ titi toto tata /;
while(<FICHIER>){
  foreach my $e(@termes_plur){
    s/(.*)$e(.*)/${1}<balise>${e}<\/balise>$2/g if /(.*)$e(.*)/;
  }
  print ECRIRE;
}
lami20j@debian:~/trash$ perl mots_0.pl
lami20j@debian:~/trash$ cat resultat_phrases_0.txt
ligne 1 <balise>toto</balise> et <balise>titi</balise>
ligne 2 <balise>tata</balise>
ligne 3 rien
<balise>titi</balise> <balise>toto</balise> <balise>tata</balise>
lami20j@debian:~/trash$


Et la version 2 de script
lami20j@debian:~/trash$ cat phrases.txt
ligne 1 toto et titi
ligne 2 tata
ligne 3 rien
titi toto tata
lami20j@debian:~/trash$ cat mots.pl
#!/usr/bin/perl
use strict;use warnings;

open FICHIER,"phrases.txt" or die "E/S : $!\n";
open ECRIRE,">>resultat_phrases.txt" or die "E/S : $!\n";

my @termes_plur=qw/ titi toto tata /;
while(<FICHIER>){
  foreach my $e(@termes_plur){
    if (/$e/){
      s/(?=$e)/<balise>/g;
      s/(?<=$e)/<\/balise>/g;
    }
  }
  print ECRIRE;
}
lami20j@debian:~/trash$ perl mots.pl
lami20j@debian:~/trash$ cat resultat_phrases.txt
ligne 1 <balise>toto</balise> et <balise>titi</balise>
ligne 2 <balise>tata</balise>
ligne 3 rien
<balise>titi</balise> <balise>toto</balise> <balise>tata</balise>
lami20j@debian:~/trash$
0
marge31 Messages postés 3 Date d'inscription lundi 27 juillet 2009 Statut Membre Dernière intervention 28 juillet 2009
28 juil. 2009 à 13:44
Bonjour,

merci beaucoup de ton aide. Le script fonctionne mais j'ai encore un problème que j'avais pas prévu !! comme je te le disais, je peux avoir des termes comme "manoeuvre de libération" mais aussi "manoeuvre" tout court. Dans ce cas, quand le prog tombe sur "manoeuvre de libération", il fait un double balisage : il commence par baliser manoeuvre puis manoeuvre de libération ce qui donne <balise><balise>manoeuvre </balise> de libération </balise>. J'ai essayé de faire un tri sur le tableau @terme_plur mais sans succés. Y'a t il selon toi une solution ou c'est peine perdue?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
28 juil. 2009 à 14:01
Salut,

Y'a t il selon toi une solution ou c'est peine perdue?
Ben, je suis plutôt optimiste ;-))

Je vais regarder ce soir.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
29 juil. 2009 à 03:12
Salut,

Teste ça (le script en gras)
lami20j@debian:~/trash$ cat phrases.txt
manoeuvre
manoeuvre de liberation
titi toto
tata titi et toto
lami20j@debian:~/trash$ cat mots_1.pl
#!/usr/bin/perl
use strict;use warnings;

open FICHIER,"phrases.txt" or die "E/S : $!\n";
open ECRIRE,">>resultat_phrases.txt" or die "E/S : $!\n";
my @t;
my @termes_plur=("titi","toto", "manoeuvre de liberation", "titi et toto","manoeuvre","tata");

my @tri = map  {$_->[1]}
          sort {$a->[0] < $b->[0]}
          map  { @t= split /\s+/,$_ and [@t + 0, $_] }
          @termes_plur;

while(<FICHIER>){
  foreach my $e(@tri){
      if (/(?<!>)$e(?!<)/){
        s/(?<=$e)/<\/balise>/g;
        s/(?=$e)/<balise>/g;
      }
    }
  print ECRIRE;
}
lami20j@debian:~/trash$ perl mots_1.pl
lami20j@debian:~/trash$ cat resultat_phrases.txt
<balise>manoeuvre</balise>
<balise>manoeuvre de liberation</balise>
<balise>titi</balise> <balise>toto</balise>
<balise>tata</balise> <balise>titi et toto</balise>
0