#!/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]; }