Version HTML du script entrainement-entites.pl

Pour télécharger le script : cliquez ici

#!/usr/bin/perl

<<DOC; 
Axel COURT & Marjorie SEIZOU
AVRIL 2010

usage : perl entites.pl	<FichierCordial>

DOC

use WWW::Wikipedia;
use Encode;
use utf8;

# Création des objets WWW::Wikipedia français et anglais
my $wiki_fr = WWW::Wikipedia->new( language => 'fr' );
my $wiki_en = WWW::Wikipedia->new( language => 'en' );

# Ouverture d'un fichier taggé par Cordial
open(CORDIAL, "<:encoding(utf8)", "$ARGV[0]") or die "Probleme a l'ouverture du fichier Cordial : $!\n";

# Ouverture de la sortie
open(ENTITES, ">:encoding(utf8)", "entites.txt");

# Initialisation des variables
# %wiki contient les données Wikipédia sur l'entité, %poubelle contient la liste des suspects éliminés 
# (pour éviter de parcourir plusieurs fois inutilement l'encyclopédie)
my %wiki;
my %poubelle;
my %compteoccurrences;
my %lien;
my $name = "";

# Parcours du fichier taggé
&parcourstag;

# Ecriture du fichier de sortie : on vide nos hash
@keys = sort keys %wiki;
foreach $key (@keys) {
	if ($key ne "") {
		print ENTITES $key."\t".$compteoccurrences{lc($key)}."\t".$lien{$key}."\n";
		print ENTITES $wiki{$key}."\n\n";
		print ENTITES "-----------------------------------------------------------------------------------\n";
	}
}
close(ENTITES);

# Adieu !
exit;

############################################################

# Procédure de parcours du fichier taggé
sub parcourstag {
	# Le principe est de trouver les plus grandes suites de mots taggés "NP" (Noms Propres)
	# Puis, on recherche dans Wikipédia français (et anglais si besoin) si la supposée entité nommée existe
	# Si oui, on récupère ses informations et on les traite ; si non, on considère que ce n'est pas une entité nommée et on l'élimine de la liste des suspects
	while (my $ligne = <CORDIAL>) {
		if ($ligne =~ /^(.+)\t(.+)\t(NP.+)$/) {
			# On "garnit" la variable $name de mots taggés "NP" et qui se suivent
			$name .= $1." ";
		}
		elsif ($ligne !~ /^(.+)\t(.+)\t(NP.+)$/ and $name ne "") {
			# Si on est passé à une autre catégorie syntaxique, mais qu'on a du contenu dans $name : bref, si on a un candidat
			$name =~ s/^(.+)\s$/$1/g;
			$name =~ s/-/ /g;
			$name =~ s/  +/ /g;
			$name =~ s/ /_/g;
			$name =~ s/^_(.+)$/$1/g;
			if ($name =~ /^[A-Z]'(.+)$/) {
				my $temp = $1;
				if ($temp =~ /[A-Z].+/) {
					$name = $temp;
				}
				else { $name = ""; }
			}
			$name2 = $name;
			$name2 =~ s/_/ /g;
			$name3 = lc($name2);
			if ( not exists ($compteoccurrences{$name3}) and not exists ($poubelle{$name3}) ) {
				# Vérification du candidat dans Wikipédia français
				# print "Entité trouvée ($name2) : une visite sur Wikipédia fr s'impose !\n";
				my $result = $wiki_fr->search( $name2 );
				if ( not defined($result) ) {
					# Si la recherche en français est infructueuse, on cherche dans Wikipédia anglais
					# print "Oups, je suis obligé de passer à Wikipédia en !\n";
					my $result = $wiki_en->search( $name2 );
				}
				if ( defined($result) ) { 
					# Si un article WIkipédia a été trouvé, on a bien une entité nommée !
					$texte = $result->text_basic();
					$texte = Encode::decode("utf8", $texte);
					# Lancement de la procédure pour nettoyer le texte
					&traitementarticle;
				    $wiki{$name2} = $texte;
				    $lien{$name2} = "http://fr.wikipedia.org/wiki/$name";
				   	$compteoccurrences{$name3}++;
				}
				else { 
					# Si aucun article n'a été trouvé, on élimine la supposée entité de la liste, 
					# et on la stocke dans un coin pour éléminier d'office ses prochaines éventuelles occurrences
					$poubelle{$name3}++
				}
				$name = "";
				$result = "";
			}
			else { 
				$compteoccurrences{$name3}++;
				$name = "";
			} 
		}
		else {
			# Traitement des lignes normales 
			}
		}
	close(CORDIAL);
}

# Procédure de traitement de l'article
sub traitementarticle {
	$texte =~ s/\n/ /g;
	$texte =~ s/<ref([^>]+)?>.+?<\/ref>/ /g;
	my $texteformate = "";
	# Récupération des informations de l'Infobox, s'il y en a un
	# (la plupart sont récupérées, certaines laissées de côté par manque d'harmonisation du flux d'entrée)
	if ($texte =~ /Infobox\s*(.+?)\s*\|/i) {
		my $val = $1;
		&nettoyagetexte($val);
		$texteformate .= "[[Type=$val]]\n";
	}
	while ($texte =~ /\|\s*([^\|]+?)\s*=\s*([^\|]+?)\s*\|/g) {
		if ($2 !~ /^\s*$/) {
			my $cat = $1;
			my $val = $2;
			&nettoyagetexte($cat);
			&nettoyagetexte($val);
			$texteformate .= "{{$cat=$val}}\n";
		}
	}
	$texte = $texteformate;
}

sub nettoyagetexte {
	$_[0] =~ s/<ref([^>]+)?>.+?<\/ref>/ /g;
	$_[0] =~ s/<.+?>/ /g;
	$_[0] =~ s/_/ /g;
	$_[0] =~ s/\(\)//g;
	$_[0] =~ s/\]\]/ /g;
	$_[0] =~ s/\[\[/ /g;
	$_[0] =~ s/\{\{.+?\}\}/ /g;
	$_[0] =~ s/\s+/ /g;
	return $_[0];
}