Le langage Perl est particulièrement bien adapté aux manipulations de texte. Dans ce TP (en ce jour de Saint-Valentin), nous verrons quelques exemples appliqués au texte complet de la tragédie de William Shakespeare, Roméo et Juliette.

L'élève curieux pourra également se reporter au TP analogue proposé en 2007 par Antoine Miné.

Aide

On rappelle qu'un script script Perl est un fichier texte d'extension .pl, tel toto.pl, qui commence par une ligne précisant l'interpréteur:

#!/usr/bin/perl -W

et qui est rendu exécutable par la commande chmod +x toto.pl. Dans cet exemple, on a forcé l'option -W qui active tous les avertissements paranoïaques de Perl (voir perlrun(1)).

Liens utiles:

top

Exercice 1 - Affichage

  1. Écrire le programme Hello World! en Perl.

    #!/usr/bin/perl -W
    print("Hello World!");



  2. Écrire un script qui affiche le contenu d'un fichier dont le chemin est passé en argument.

    #!/usr/bin/perl -W
    while (<>) { print ; }



  3. Modifier votre script pour qu'il n'affiche que les lignes impaires (ou les lignes dont les indices sont contenus dans un intervalle, ou ...)

    #!/usr/bin/perl -W

    if ($#ARGV<0)
    {
        while ($line = ) { print $line; }
    }
    else
    {
       my $i=$ARGV[0];
       my $j=0;

       open (FILE,"$i") or die "$i :$!";
       while ($line = ) { print $line if($j%2==0); $j++;}
       close FILE
    }
    # Le fichier sand.txt est un exemple de steganographie

(Ces scripts pourront être testés sur le texte de Roméo et Juliette ou encore sur cet exemple). top

Exercice 2 - Textométrie

  1. Écrire un script qui transforme un fichier texte en un fichier contentant une phrase du fichier par ligne.

    #!/usr/bin/perl -W

    open(Fic, $ARGV[0]);

    $Out="Phrases_$ARGV[0]";
    open(Sortie,">$Out");

    my $i=0;@car = (Fic);

    while(!eof(Fic))
    {
       $car[$i]=getc(Fic);
       if ($car[$i] eq "\n") {$car[$i]=' ';}
       $i++ unless ($car[$i] eq " ")&&($car[$i-1] eq " ");
    }
    close(Fic);

    $car[$i]="\0";

    $i=0;

    while($car[$i] ne "\0")
    {
       print Sortie $car[$i];
      
       if( ($car[$i] eq "\.") && ($car[$i+1] ne "\.") && ($car[$i-1]=~ /[^A-Z]/) &&
       ($car[$i-1]=~ /[^0-9]/) && ($car[$i+2]=~/[A-Z]/))
       {
         print Sortie "\n";
         $i++;
       }
      
       if(($car[$i] eq "\.") && ($car[$i-1] eq "\.") &&
       ($car[$i-2] eq "\.") && ($car[$i+2]=~/[A-Z]/))
       {
         print Sortie "\n";
         $i++;
       }
      
       if((($car[$i] eq "!") || ($car[$i] eq "\?")) &&
         ($car[$i+2]=~/[A-Z]/))
       {
         print Sortie "\n";
         $i++;
       }
      
       $i++;
    }

    close(Sortie);



  2. Écrire un script qui affiche la phrase la plus longue et la plus courte d'un fichier texte.

    #!/usr/bin/perl -W

    open(FIC, $ARGV[0]); # Lit le fichier SEGMENTE en phrases

    $i = 0; @ph = ();

    foreach $ligne()
    {

      if($ligne !~ /^$/)
      {
         if ($i == 0)
         {
           $ph[$i] = $ligne; chomp $ligne;
           $maxlong=0;$minlong=0;
           $i++;
         }
         else
         {
           $ph[$i] = $ligne; chomp $ligne;
           if (length($ligne)>length($ph[$maxlong])) {$maxlong=$i;}
           if (length($ligne)        $i++;
         }
      }
    }

    print "Phrase la plus longue : \n\t$ph[$maxlong]\n";
    print "Phrase la plus courte : \n\t$ph[$minlong]\n";
    close(FIC);



  3. Écrire un script qui compte le nombre d'occurrences des mots d'un fichier texte
    (rapporter la fréquence de chaque mot ordonné alphabétiquement).

    #!/usr/bin/perl -W

    $/ = "";

    while (<>)
    {
       #s/-\n//g;
       tr/A-Z/a-z/;
       @mots = split(/\W*\s+\W*/, $_);
       foreach $mot (@mots)
       {
         $combienmots{$mot}++;
      }
    }

    foreach $mot (sort keys(%combienmots))
    {
       printf "%8d\t%s\n", $combienmots{$mot}, $mot;
    }



    Modifier votre script pour qu'il compte le nombre de fois où chaque personnage s'exprime et le nombre de total de lignes prononcées par chaque personnage dans la pièce Roméo et Juliette.


  4. Une concordance donne pour un mot l'ensemble des passages d'un texte (ou d'un ensemble de textes) le contenant.
    Écrire un script qui prend un argument un mot et un fichier texte et retourne toutes les occurences de ce mot dans le document précédées des trois mots précédents et suivis des trois mots suivants dans le texte.

    #!/usr/bin/perl

    $usage = "$0 mot fichier\n";

    $lgauche = 40;
    $ldroite = 40;
    $mot = shift or die $usage;
    $longmot = length($mot);
    $fichier = shift or die $usage;
    open (F, $fichier) or die $usage;
    while ()
    {
       chomp;
       $longphrase = length($_);
       $decalage = 0;
       $indicetrouve = index($_, $mot, $decalage);
       while ($indicetrouve != -1)
       {

         $dgauche = $indicetrouve-1;
         $k=0;
         while (($k<3)&&(rindex($_," ",$dgauche-1) !=-1))
         {
           $dgauche = rindex($_," ",$dgauche-1);
           $k++
         }
         $dgauche=max($dgauche,$indicetrouve-$lgauche);
         print (' ' x ($lgauche-($indicetrouve-$dgauche)));
         print (substr($_, $dgauche, $indice-$dgauche-1));

         print (' ', $mot, ' ');

         $ddroite = min($longphrase,$indice + $longmot);
         $fdroite = $ddroite;
         $k=0;
         while (($k<3)&&(index($_," ", $fdroite+1) !=-1))
         {
           $fdroite = index($_," ",$fdroite+1);$k++
         }
         $tdroite=min($fdroite-$ddroite,$ldroite);
         print substr($_,$ddroite,tdroite));
         print "\n";

         $decalage = $indice+1;
         $indice = index($_, $mot, $decalage);
       }
    }
    close(F);

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

    sub min {
       my($x,$y) = @_;
       return ($x < $y) ? $x : $y;
    }

    sub max {
       my($x,$y) = @_;
       return ($x > $y) ? $x : $y;
    }


top

Exercice 3 - Conversion HTML d'une pièce de théâtre

  1. Écrire un script qui convertit le texte de la pièce Roméo et Juliette en un ensemble de documents HTML :

    1. chaque acte apparaît dans un fichier HTML distinct ;

    2. le nom du personnage qui s'exprime est centré par rapport au texte et apparaît en gras
      (on pourra tenter une version plus colorée où le nom de chaque personnage apparaît avec une couleur différente) ;

    3. les didascalies apparaîssent en italique et sans crochets ;

    4. une table des matières permettant d'accéder directement à chaque scène est fournie
      (cette table des matières devra faire apparaître le nom des personnages qui apparaîssent dans chacune des scènes) ;

    5. une page présentant les personnages, avec la liste de ses répliques et un lien vers celles-ci, est fournie ;
      par exemple pour Lady Capulet, la page devra commencer par
      1 I,1 A crutch, a crutch! why call you for a sword?
      2 I,3 Nurse, where's my daughter? call her forth to me.

    6. ...


  2. Trouver une traduction française (par exemple) de la pièce et afficher une version bilingue (en synchronisant les répliques).
top