bao3Boîte à Outils 3


Trois méthodes ont été mises à notre disposition :

La méthode PURE PERL proposée par Jean Michel Daube

C'est un programme pure perl qui a pour but d'extraire les patrons étiquetés avec le logiciel cordial. open(CORDIAL,"<$ARGV[1]"); Il prend en argument les étiquetés par Cordial, le chemin du dossier de sortie et un fichier de patrons syntaxiques. Le programme va lire le fichier ligne par ligne et chaque ligne contient trois éléments qui formes, lemmes et catégories syntaxiques. L'étiquette "PCTFORTE" fait un traitement de phrase par phrase s'il est indiqué en fin de phrase et stocke les résultats dans trois tableaux différents. Ici nous devons extraire ces patrons listés ci-dessous grâce à ce programme NOM ADJ NOM PREP NOM VERB DET NOM VERB PREP NOM

La méthode de Serge Fleury :

Elle est basée sur les expressions régulières et prend pour argument soit un fichier étiqueté par Treetagger ou un fichier annoté par Cordial. Le programme débute par la boucle «while» et contient deux importantes variables: my $sequence mémorise les formes. my $longueur compte les formes récupérées par séquences. $1 recupère chaque élément du patron morphosyntaxique à traiter. Le programme lit ligne par ligne et insère dans une variable(@lignes) chaque ligne lue. Il parcourt aussi les listes de POS et essaye de trouver toutes les listes qui renvoient aux motifs du fichiers des patrons. Comme ce script nous fournira en sortie que les patrons « Nom ADJ » nous avions dû le modifier pour qu'il traite aussi des patrons « NOM PREP NOM »

La méthode de JMD : Avec les sorties de cordial

Chaque fichier de patron est associé au script comme deuxième argument pour obtenir les différents résultats.

#!/usr/bin/perl
# Le programme de JMD...
# lecture du fichier cordial et d'un fichier de patrons
# IMPORTANT : TOUT EST EN ISO.
#-----------------------------------------------------------
# 1er argument : le fichier des patrons morphosyntaxiques
open(TERMINO,"<$ARGV[0]");
while (my $terme=<TERMINO>) {
	chomp($terme);
	$terme=~s/ +/ /g;
	$terme=~s/\r//g;
	open(CORDIAL,"<$ARGV[1]");
	my @POS=();
	my @TOKEN=();
	while (my $ligne=<CORDIAL>) {
		chomp($ligne);
		$ligne=~s/\r//g;
		if ($ligne!~/PCT/) {
			my @LISTE=split(/\t/,$ligne);
			#print "PATRON LU <$terme> : Ligne lue <@LISTE>\n";
			push(@POS,$LISTE[2]);
			push(@TOKEN,$LISTE[0]);
		}
		else {
			# on est arriv&eacute; sur une PCT, on va la traiter...
			#print "----------------------------------------\n";
			#print "<@TOKEN>\n";
			#print "<@POS>\n";
			#print "TERME CHERCHE : $terme \n";
			#my $a=<STDIN>;
			# on doit chercher si le "scalaire" $terme est dans @POS
			# pour cela on va transformer POS et TOKEN en scalaire
			# pour ensuite faire le match entre le TERME et le scalaire POS
			# si match alors on  imprime...
			my $pos=join(" ",@POS);
			my $token=join(" ",@TOKEN);
			my $cmptdetrouvage=0;
			while ($pos=~/$terme/g) {
				$cmptdetrouvage++;
				#print "Youpi, TROUVE $cmptdetrouvage fois \n ";
				#print "En effet : $terme est bien dans $pos !!!!\n";
				my $avantlacorrespondance=$`;
				# on compte le nb de blanc dans avantlacorrespondance et dans terme...
				#--------------------------------------------------------------------------
				# SUPER METHODE : my $comptagedeblanc = () = $avantlacorrespondance=~/ /g;
				#-------------------------------------------------------------------------
				# autre methode : avec un while
				my $comptagedeblancdansterme=0;
				while ($terme=~/ /g) {
					$comptagedeblancdansterme++;
				}
				my $comptagedeblanc=0;
				#print "AVANT : $avantlacorrespondance \n";
				while ($avantlacorrespondance=~/ /g) {
					$comptagedeblanc++;
				}
				for (my $i=$comptagedeblanc;$i<=$comptagedeblanc+$comptagedeblancdansterme;$i++) {
					print $TOKEN[$i]." ";
				}
				print "\n";
			}
			# c'est fini pour la recherche du match
			# on vide les 2 listes de travail avant de recommencer de les remplir
			@POS=();
			@TOKEN=();
		}
	}
	close(CORDIAL);
}
close(TERMINO);
#-----------------------------------------------------------
 

La méthode de SF : Avec les sorties Treetagger

open(FILE,"$ARGV[0]");
#--------------------------------------------
# le patron cherch&eacute; ici est du type NOM ADJ";
# le modifier pour extraire NOM PREP NOM
#--------------------------------------------
my @lignes=<FILE>;
close(FILE);
while (@lignes) {
    my $ligne=shift(@lignes);
    chomp $ligne;
    my $sequence="";
    my $longueur=0;
    if ( $ligne =~ /<element><data type=\"type\">NOM<\/data><data type=\"lemma\">[^<]+<\/data><data type=\"string\">([^<]+)<\/data><\/element>/) {
	 my $forme=$1;
	 $sequence.=$forme;
	 $longueur=1;
	 my $nextligne=$lignes[0];
	 if ( $nextligne =~ /<element><data type=\"type\">ADJ<\/data><data type=\"lemma\">[^<]+<\/data><data type=\"string\">([^<]+)<\/data><\/element>/) {
	     my $forme=$1;
	     $sequence.=" ".$forme;
	     $longueur=2;
	 }
    }
    if ($longueur == 2) {
	print $sequence,"\n";
    }
}

La méthode de Rachid Belmouhoub (RB)

Le script prend en argument un fichier de sortie en format xml et un fichier de patrons morphosyntaxiques.

Une fois qu'il a ouvert le fichier il va le lire et il nous renverra un motif par ligne.

open(PATTERNSFILE, $patterns_file) or die "can't open $patterns_file: $!\n"; while (my $ligne = ) { &extract_pattern($ligne); }

La fonction &extract_pattern($ligne) va donner autant de motifs que de fichiers de sortie grâce au chemin Xpath créé. On sera appelé aussi à recourir à des requêtes Xpath qu'on intégrera dans le script mais aussi à installer le module XML::XPATH dans notre bibliothèque Perl. Ceci permettra de récupérer des tokens, des lemmes et des catégories morphosyntaxiques. Par ailleurs, la fonction &construit_Xpath crée les chemins Xpath en prenant comme argument la ligne du patron. Une liste sera créée avec la ligne du patron choisi

#/usr/bin/perl
<<DOC; 
Nom : Rachid Belmouhoub
Avril 2012
 usage : perl bao3_rb_new.pl fichier_tag fichier_motif
DOC
 
use strict;
use utf8;
use XML::LibXML;
 
# Définition globale des encodage d'entrée et sortie du script à utf8
binmode STDIN,  ':encoding(utf8)';
binmode STDOUT, ':encoding(utf8)';
 
# On vérifie le nombre d'arguments de l'appel au script ($0 : le nom du script)
if($#ARGV!=1){print "usage : perl $0 fichier_tag fichier_motif";exit;}

# Enregistrement des arguments de la ligne de commande dans les variables idoines
my $tag_file= shift @ARGV;
my $patterns_file = shift @ARGV;
 
# création de l'objet XML::XPath pour explorer le fichier de sortie tree-tagger XML
my $xp = XML::LibXML->new(XML_LIBXML_RECOVER => 2);
$xp->recover_silently(1);
 
my $dom    = $xp->load_xml( location => $tag_file );
my $root   = $dom->getDocumentElement();
 
my $xpc    = XML::LibXML::XPathContext->new($root);
 
# Ouverture du fichiers de motifs
open(PATTERNSFILE, $patterns_file) or die "can't open $patterns_file: $!\n";
 
# lecture du fichier contenant les motifs, un motif par ligne (par exemple : NOM ADJ)
while (my $ligne = <PATTERNSFILE>) {
        # Appel à  la procédure d'extraction des motifs
        &extract_pattern($ligne);
}
 
# Fermeture du fichiers de motifs
close(PATTERNSFILE);
 
# routine de construction des chemins XPath
sub construit_XPath{
        # On récupère la ligne du motif recherché
        my $local_ligne=shift @_;
 
        # initialisation du chemin XPath
        my $search_path="";
 
        # on supprime avec la fonction chomp un éventuel retour à la ligne
        chomp($local_ligne);
 
        # on élimine un éveltuel retour chariot hérité de windows
        $local_ligne=~ s/\r$//;
 
        # Construction au moyen de la fonction split d'un tableau dont chaque élément a pour valeur un élément du motif recherché
        my @tokens=split(/ /,$local_ligne);
 
        # On commence ici la construction du chemin XPath
        # Ce chemin correspond au premier noeud "element" de l'arbre XML qui répond au motif cherché 
        $search_path="//element[contains(data[\@type=\"type\"],\"$tokens[0]\")]";
 
        # Initialisation du compteur pour la boucle de construction du chemin XPath
        my $i=1;
        while ($i < $#tokens) {
                $search_path.="[following-sibling::element[1][contains(data[\@type=\"type\"],\"$tokens[$i]\")]";
                $i++;
        }
        my $search_path_suffix="]";
 
        # on utilise l'opérateur x qui permet de répéter la chaine de caractère à sa gauche autant de fois que l'entier à sa droite,
        # soit $i fois $search_path_suffix
        $search_path_suffix=$search_path_suffix x $i;
 
        # le chemin XPath final
        $search_path.="[following-sibling::element[1][contains(data[\@type=\"type\"],\"".$tokens[$#tokens]."\")]"
                                                                .$search_path_suffix;
                # print  "$search_path\n";

        # on renvoie à la procédure appelante le chein XPath et le tableau des éléments du motif
        return ($search_path,@tokens);
}
 
# routine d'extraction du motif
sub extract_pattern{
        # On récupère la ligne du motif recherché
        my $ext_pat_ligne= shift @_;
 
        # Appel de la fonction construit_XPath pour le motif lu à la ligne courrante du fichier de motif
        my ($search_path,@tokens) = &construit_XPath($ext_pat_ligne);
 
        # définition du nom du fichier de résultats pour le motif en utilisant la fonction join
        my $match_file = "res_extract-".join('_', @tokens).".txt";
 
        # Ouverture du fichiers de résultats encodé en UTF-8
        open(MATCHFILE,">:encoding(UTF-8)", "$match_file") or die "can't open $match_file: $!\n";
 
        # création de l'objet XML::XPath pour explorer le fichier de sortie tree-tagger XML
        
        # Parcours des noeuds du ficher XML correspondant au motif, au moyen de la méthode findnodes
        # qui prend pour argument le chemin XPath construit précédement
        # avec la fonction "construit_XPath"
        my @nodes=$root->findnodes($search_path);
        foreach my $noeud ( @nodes) {
                # Initialisation du chemin XPath relatif du noeud "data" contenant
                # la forme correspondant au premier élément du motif
                # Ce chemin est relatif au premier noeud "element" du bloc retourné
                # et pointe sur le troisième noeud "data" fils du noeud "element"
                # en l'identifiant par la valeur "string" de son attribut "type"
                my $form_xpath="";
                $form_xpath="./data[\@type=\"string\"]";
 
                # Initialisation du compteur pour la boucle d'éxtraction des formes correspondants
                # aux éléments suivants du motif
                my $following=0;
 
                # Recherche du noeud data contenant la forme correspondant au premier élément du motif          
                # au moyen de la fonction "find" qui prend pour arguments:
                #                       1. le chemin XPath relatif du noeud "data"
                #                       2. le noeud en cours de traitement dans cette boucle foreach
                # la fonction "find" retourne par défaut une liste de noeuds, dans notre cas cette liste
                # ne contient qu'un seul élément que nous récupérons avec la fonction "get_node"
                # enfin nous en imprimons le contenu textuel au moyen de la méthode string_value
                print MATCHFILE $xpc->findvalue($form_xpath,$noeud);
 
                # Boucle d'éxtraction des formes correspondants aux éléments suivants du motif
                # On descend dans chaque noeud element du bloc
                while ( $following < $#tokens) {
                        # Incrémentation du compteur $following de cette boucle d'éxtraction des formes
                        $following++;
 
                        # Construction du chemin XPath relatif du noeud "data" contenant
                        # la forme correspondant à l'élément suivant du motif
                        # Notez bien l'utilisation du compteur $folowing tant dans la condition de la boucle ci-dessus
                        # que dans la construction du chemin relatif XPath
                        my $following_elmt="following-sibling::element[".$following."]";                        
                        $form_xpath=$following_elmt."/data[\@type=\"string\"]";
 
                        #       Impression du contenu textuel du noeud data contenant la forme correspondant à l'élément suivant du motif
                        print MATCHFILE " ",$xpc->findvalue($form_xpath,$noeud);
 
                        # Incrémentation du compteur $following de cette boucle d'éxtraction des formes
                        # $following++;
                }
                print MATCHFILE "\n";
        }
        # Fermeture du fichiers de motifs
        close(MATCHFILE);
}
 
Accueil BaO2 BaO4 Haut de page