Série 3 : Patrons syntaxiques
Il s'agit ici d'ajouter au programme de la série 2 un programme
d'extraction de patrons syntaxiques.
TreeTagger
On modifie le programme précédent pour
créer un fichier
comportant l'ensemble des phrases étiquetées par
le TreeTagger sur lequel on applique ensuite l'extraction.
Par exemple pour rechercher le patron NOM ADJ on utilise le fichier patron et
on obtient cette extraction.
On obtient cette extraction en plus du fichier xml
étiqueté.
Le contenu du
programme (les changements par rapport à la
série 2 sont en vert) :
#!/usr/bin/perl
<<DOC;
Format d\'entree : un texte étiqueté et
lemmatisé par tree tagger
Format de Sortie : le même texte au format xml
DOC
# Usage
$ChaineUsage="Usage : tt2xml.pl <Fichier>\n";
if (@ARGV!=1) {
die $ChaineUsage;
}
$t=0;
&ouvre;
&entete;
my $rep="$arg";
# on s'assure que le nom du répertoire ne se termine pas par
un "/"
$rep=~ s/[\/]$//;
print "Quelle est la balise à extraire ?\n";
$exp=<STDIN>;
chomp $exp;
# On choisit le nom du fichier qui
contiendra les patrons extraits
print "choisis un nom de fichier pour contenir les termes extraits\n";
# Entrer le nom du fichier contenant les patrons
$fic=<STDIN>;
print "Quel est le fichier contenant les patrons?\n";
$pat=<STDIN>;
&parcoursarborescencefichiers($rep);
&fin;
&ferme;
# On appelle le sous programme
d'extraction
&patron;
# Récupération des arguments et ouverture des
tampons
sub ouvre {
$arg = $ARGV[0];
$FichierSortie= $arg . ".xml";
open(Sortie,">$FichierSortie");
open(TP,">pourpatron.txt");
}
# Entête de document XML
sub entete {
print Sortie "<?xml version=\"1.0\" encoding=\"iso-8859-1\"
standalone=\"no\"?>\n<?xml-stylesheet type=\"text/xsl\"
href=\"StyleT.xsl\"?>\n";
print Sortie
"<document>\n<Nom>Aurélia
Trinquier</Nom>\n";
}
sub parcoursarborescencefichiers {
my $path = shift(@_);
opendir(DIR, $path) or die "ne peut ouvrir $path: $!\n";
my @files = readdir(DIR);
closedir(DIR);
foreach my $file (@files) {
next if $file =~ /^\.\.?$/;
$file = $path."/".$file;
if (-d $file) {
&parcoursarborescencefichiers($file); #recurse!
}
if (-f $file) {
# TRAITEMENT à réaliser sur chaque fichier
open(FILEINPUT,$file);
print Sortie
"<fichier>\n<nom>$file</nom>\n";
while ($ligne = <FILEINPUT>)
{
if ($ligne=~/<$exp>(.*)<\/$exp>/)
{ open(OUTPUT,">resultats.txt");
print Sortie "<description>\n";
$ligne=$1;
# Rectification des problèmes de codage
$ligne=~s/(')/\'/g;
$ligne=~s/(")/\"/g;
$ligne=~s/à©/é/g;
$ligne=~s/é/é/g;
$ligne=~s/ê/ê/g;
$ligne=~s/è/è/g;
$ligne=~s/Ã/à/g;
$ligne=~s/ç/ç/g;
$ligne=~s/à§/ç/g;
$ligne=~s/à´/ô/g;
$ligne=~s/(é)/é/g;
$ligne=~s/(ê)/ê/g;
# Séparation du texte en 1 mot par ligne
$ligne=~s/( )/\n/g;
$ligne=~s/([,\;:!?\.'\"\(\)])/\n$1\n/g;
print OUTPUT $ligne;
#Fermeture du fichier resultats.txt
close(OUTPUT);
#Lancement du TreeTagger
system ("bin/tree-tagger.exe -token -lemma lib/french.par resultats.txt
treetagger.txt");
open(TREE,"treetagger.txt");
while ($tree = <TREE>) {
# On imprime la phrase
étiquetée dans le fichier pourpatron.txt
print TP $tree;
if ($tree!~/\ô\¯\:\.\ô\¯\:\.\./ )
{
# Remplacement des guillemets par <![CDATA["]]>
(évite erreur d'interprétation XML)
$tree=~s/\"/<![CDATA[\"]]>/g;
$tree=~s/(<unknown>)/unknown/g;
# Suppression des caractères
générés par TreeTagger
empêchant la bonne formation du fichier xml
$tree=~s/(.*°I..)//g;
$tree=~s/([^\t]*)\t([^\t]*)\t([^\n]*)\n/<element>\n
<data type=\"cat\">$2<\/data>\n
<data type=\"lemme\">$3<\/data>\n
<data
type=\"mot\">$1<\/data>\n<\/element>/;
print Sortie $tree;
}
}
close(TREE);
print Sortie "\n</description>\n";
}
}
print Sortie "</fichier>\n";
}
# Fin de fichier
sub fin {
print Sortie "</document>\n";
close (TP);
}
}
}
# Fermeture des tampons
sub ferme {
close(Sortie);
}
# Insertion du programme d'extraction
sub patron {
# On change le nom du fichier à traiter
open(FIC, "pourpatron.txt");
# ouverture d un fichier de trace, destine a recevoir les
# informations de traitements
#---------------------------------------------------
# initialisation des variables
#---------------------------------------------------
open(FIC1, ">$fic");
my $i=0;
my $j=0;
my $k=0;
my @token=();
#---------------------------------------------------
# lecture du fichier de sortie TREETAGGER
# creation de 3 tableaux contenant les mots, les lemmes et les
categories
#---------------------------------------------------
while (<FIC>) {
my $ligne=$_;
my @liste=split(/\t/,$ligne);
push(@token, $liste[$i++]." ");
push(@patron, "$liste[$i++]" ." ");
push(@lemme, "$liste[$i++]" ." ");
$i=0;
}
close(FIC);
#---------------------------------------------------
# on cree une liste vide destinee a recevoir les patrons
# presents dans le fichier lu a l etape precedente
# cette liste sera initialisee apres chaque construction
# de patron
#---------------------------------------------------
@sous_patron=();
#---------------------------------------------------
# creation de la liste des patrons lus dans le fichier
# issu de treetagger
#---------------------------------------------------
while (defined($element_patron=shift(@patron))) {
if ($element_patron !~ PUN && $element_patron !~ SENT)
{
push(@sous_patron, $element_patron);
$j++;
next;
}
my @sous_token=@token[$k+1..$j-1];
# on va maintenant voir si le sous-patron construit est dans le
# liste des patrons cherches (dans le fichier des patrons scrutes)
&cherche_patron(@sous_patron);
@sous_patron=();
$k=$j;
$j++;
}
close (FIC1);
#=============================================
# procedure de recherche des patrons
#=============================================
sub cherche_patron {
my @liste=@_;
my $suite_de_patrons=join("",@liste);
$z=0;
$nb=0;
# ouverture du fichier des patrons cherches
# Ouvre le fichier dans lequel les
patrons seront extraits
open(FIC, "$pat");
while(<FIC>) {
$ligne=$_;
chomp $ligne;
$nb=0;
while ($ligne=~m/ /g) {$nb++};
$nb++;
while ($suite_de_patrons=~m/$ligne/g) {
my $avant=substr ($suite_de_patrons, 0,
pos($suite_de_patrons)-length($ligne));
while ($avant=~m/ /g) {$z++};
print FIC1 "@token[$k+$z+1..$k+$z+$nb]\n";
$z=0;
}
}
close(FIC)
}
}