Perl pb pattern matching [Fermé]

Signaler
Messages postés
3
Date d'inscription
lundi 27 juillet 2009
Statut
Membre
Dernière intervention
28 juillet 2009
-
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
-
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"}
}
}

6 réponses

Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 543
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);
Messages postés
3
Date d'inscription
lundi 27 juillet 2009
Statut
Membre
Dernière intervention
28 juillet 2009

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
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 543
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;
}
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 543
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$
Messages postés
3
Date d'inscription
lundi 27 juillet 2009
Statut
Membre
Dernière intervention
28 juillet 2009

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?
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 543
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.
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 543
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>