Habert Benoît, Cécile Fabre, Fabrice Issac, De l'écrit au numérique (constituer, normaliser et exploiter les corpus électroniques), InterEditions, 1998.
Perl Perl est l'acronyme de l'expression anglaise : Practical Extraction and Report Language.
Perl a été concu par Larry Wall pour développer des programmes dans un environnement UNIX.
Perl est un langage situé à mi-chemin entre les langages de commande(les shell d'UNIX ou, dans une
moindre mesure, MS-DOS) et le langage C .Un programme Perl (que l'on appelle aussi quelquefois script) consiste en une succession d'instructions dont l'exécution ne nécessite pas d'étape de compilation. Cependant, sa syntaxe et le nombre important de fonctions dont il dispose en font un langage plus proche de C. Perl permet d'écrire rapidement de mini-outils de manipulation de données textuelles.
Perl est présent sur de nombreux systèmes: UNIX dont il est issu, MACINTOSH, VMS, OS/2, MS-DOS et
WINDOWS (3.X/95); son apprentissage est aisé, puisqu'il reprend la syntaxe de C tout en simplifiant certains
aspects (déclarations, traitement des chaînes de caractères, etc.). 1. Notions de base
1.1. En-tête
Un programme Perl est un fichier texte, et c'est perl qui se charge de l'interpréter puis de l'exécuter. Sous système UNIX, pour être exécuté un script, Perl doit avoir la structure suivante:
#!<chemin vers interpréteur>/<nom de l'interpréteur>
<listes de commandes>
Il faut indiquer sur la première ligne l'interpréteur qui va être utilisé pour exécuter la liste de commandes. Pour perl, on a donc (installation standard) :
#!/usr/local/bin/perl
<listes de commandes Perl>
Sur d'autres systèmes, cette information n'est pas nécessaire et cette ligne n'est pas prise en compte.
1.2. Commentaires
Le caractère # est utilisé pour commenter les programmes. Pour chaque ligne, exceptée la première pour un script écrit sous UNIX, tout ce qui suit ce caractère n'est pas considéré comme faisant partie du langage.
Pour aller plus loin : Un premier programme
1.3. Variables
Les variables Perl (les scalaires) permettent d'encoder plusieurs types de données simples. Les identificateurs sont de la forme $<chaîne>, où <chaîne> est une suite de caractères qui ne doit pas contenir d'opérateur prédéfini de Perl.
Il n'existe qu'un seul type de donnée simple: les scalaires. Ce type de donnée permet de mémoriser des entiers, des chaînes de caractères et des réels. Les identificateurs sont de la forme $<suite de caractères>.
A partir de ce type simple, on compose deux types complexes:
- tableau de scalaires;
- tableau associatif de scalaires.
Deux choses importantes à savoir à propos des variables:
Scalaire
Un scalaire permet de représenter aussi bien des nombres, entiers ou réels que des chaînes de caractères. Les scalaires commencent par le caractère $. Aux opérateurs classiques de manipulation de nombres, s'ajoute l'opérateur ' . ' (point) qui effectue la concaténation de deux chaînes. Ce sont ces opérateurs qui déterminent le type du contenu de la variable.
Pour des données numériques, les guillemets ne sont pas nécessaires. On obtient un résultat identique si on écrit $a="152" ou $a=152. Une variable placée entre deux guillemets (") dans une affectation est remplacée par sa valeur. Si l'on veut éviter cela, on déspécialise le caractère $ à l'aide du caractère '\'.
$numfigure = 12 ;
$p1 = "...voir figure $numfigure pour..."
$p1 contient " . . . voir figure 12 pour . . . "
$p2 = "...voir Figure \$numfigure pour..."
$p2 contient " . . . voir figure $numfigure pour . . . "
La variable $_ est une variable prédéfinie particulière. On l'utilise pour stocker des informations fréquemment utilisées (dans la plupart des cas comme variable de boucle) et par défaut quand, dans certaines fonctions ou structures de contrôle, une variable est omise.
Pour aller plus loin : scalaires
Tableau
Un tableau de scalaires est une liste de scalaires indexée par un entier. On fait reférence à l'ensemble du tableau en préfixant l'identificateur de la variable par @. La référence à un élément particulier du tableau, qui est un scalaire, se fait en préfixant l'identificateur par un $ et en ajoutant entre crochets ([ et ]) l'indice de l'élément. On peut affecter tous les éléments d'un tableau d'un seul coup. Dans ce cas, le tableau est une liste d'éléments séparés par des virgules entre parenthèses.
L'opérateur $# donne l'indice du dernier élément du tableau et permet donc de connaître le nombre d'éléments contenus dans un tableau (indice du dernier élément + 1).
Pour aller plus loin : tableaux
Tableau associatif
Un tableau associatif est une structure qui permet de mettre en relation deux éléments de type scalaire. C'est un ensemble de couples de scalaires où l'un des éléments (la clé) référence l'autre (la valeur). En pratique on considérera un tableau associatif comme un tableau classigue où l'indice n'est pas un entier mais un scalaire. On accède à l'ensemble du tableau en préfixant l'identificateur par le caractère %. Pour accéder à un élément particulier, qui est un scalaire, on préfixe l'identificateur par un $ et on ajoute, entre accolades la valeur de l'indice.
Pour aller plus loin : tableaux associatifs
1.4. Syntaxe
Un programme Perl, comme un programme C, est une suite d'instructions terminées par un point-virgule. Pour les structures de contrôle (While, if, . . . ) les blocs de programmes sont obligatoirement délimités par des accolades ouvrantes et fermantes: { et }.
1.4.1. Entrées/sorties
La commande <PTR_FICHIER>, où PTR_FICHIER est un pointeur de fichier, permet d'accéder à un fichier. Les éléments du fichier sont lus soit ligne par ligne, en affectant le résultat de la commande à un scalaire:
$variable = <PTR_FICHIER>;
soit dans leur ensemble, en affectant le résultat de la commande à un tableau:
@tableau = <PTR_FICHIER>;
Dans ce cas, chaque élément du tableau correspond à une ligne. On crée le pointeur d'un fichier à l'aide de la commande:
open(PTR_FICHIER,<nom du fichier sur disque>);
Cette commande permet d'ouvrir un fichier en lecture, il ne faut donc pas oublier de refermer le fichier après utilisation:
close(PTR_FICHIER);
Pour créer un fichier ou pour écraser un fichier déjà existant, il faut faire précéder le nom du fichier par un chevron fermant:
open(PTR_FICHlER,"><nom du nouveau fichier sur disque>");
On écrit dans un fichier à l'aide de la commande print:
print $PTR_FICHIER "cette chaine est ecrite dans un fichier\n";c
Il existe cependant des fichiers prédéfinis:
1.4.2. Structures de contrôle
On appelle bloc une ou plusieurs instructions, suivies par des points-virgules
et obligatoirement encadrées par des accolades {. . . }.
{
Instruction1;
Instruction2;
Instruction3;
}
Expressions logiques
La syntaxe utilisée pour les expressions est presque identique à celle utilisée en C. Cependant, le fait d'utiliser des variables non fortement typées impose des opérateurs différents selon le type de test à effectuer. On distingue ainsi deux groupes d'opérateurs selon le type de variable: les variables représentant des chaînes de caractères, celles représentant des nombres, entiers ou non. Pour les valeurs numériques, les opérateurs sont identiques à ceux du C. Nous indiquons ci-dessous les opérateurs de chaînes de caractères.
On peut, comme en C, combiner plusieurs expressions à l'aide de "&&" (et) et de " || " (ou) ou utiliser la négation " ! ". Une chaîne vide, ou la valeur O (ce qui revient au même pour un scalaire), a pour valeur faux.
Syntaxe: if
1.
if ( expression)
bloc
Si l'expression est évaluée à vrai, alors bloc est exécuté;
2.
if ( expressionl )
bloc 1
else ( expression2 )
bloc 2
Si l'expression est évaluée à vrai, alors bloc 1 est exécuté, sinon bloc 2 est exécuté;
3.
if ( expressionl )
bloc 1
elsif ( expression2 )
bloc 2
.....
elsif ( expressionk )
bloc k
else
bloctoutfaux
Si l'expression i est évaluée a vrai alors le bloc i est exécuté; si aucune expression n'est vraie alors le bloc tout faux est exécuté.
Syntaxe: while
While ( expression)
bloc
Le bloc est exécuté tant que l'expression expression est évaluée a vrai.
Syntaxe: foreach
foreach variable (tableau)
bloc
Affecte itérativement les valeurs du tableau à la variable variable.
Pour aller plus loin : conditionsPour aller plus loin : contrôles
1.5. Expressions régulières
Perl offre la possibilité d'utiliser le langage des expressions régulières au travers d'opérateurs ou de fonctions.
Recherche de motif
Cet opérateur peut être comparé à l'effet de la commande UNIX grep sur un fichier d'une seule ligne.
$phrase = ~/<expression régulière>/
a pour valeur vrai si l'expression régulière apparaît dans la variable $phrase.
Recherche et remplacement
$phrase =~s/<expression régulière>/<motif de remplacement>/<options>
remplace dans la variable $phrase la ou les occurrences de l'expression régulières par le motif de remplacement.
Pour aller plus loin : recherche expression régulièrePour aller plus loin : remplacement expression régulière
Pour aller plus loin : manuel expression régulière
1.6. Premiers programmes Perl
Exemple 0 : comptage de lignes
Ce premier programme affiche chaque ligne d'un fichier précédée de son numéro.
#!/usr/local/bin/perl
#!/usr/local/bin/perl
$numligne = 0;
while ($ligne=<STDIN>) {
print $numligne."\t".$ligne;
$numligne++;
}
Exemple 1: Comptage de balise
On souhaite connaître le nombre de balise d'un certain type présentes dans le fichier de travail. Pour chaque ligne, nous allons compter le nombre d'occurrences de la balise <balise>. Pour cela, on parcourt tout le fichier de données ligne par ligne et pour chaque ligne on regarde si elle commence par la balise <balise>. Si c'est le cas, alors on incrémente un compteur.
#!/usr/local/bin/perl
while(<STDIN>)
{
if (/^<balise>/)
{
$nb++;
}
}
print "Il y a $nb références\n";
Le programme est constitué d'une boucle while qui permet de parcourir tout le fichier de données.
L'expression if (/^<balise/) est un test, elle retourne vrai si la chaîne de caractères lue est couverte par l'expression régulière placée entre les barres obliques (slash). Le programme se lit donc de la manière suivante: pour chaque ligne du fichier d'entrée standard, si cette ligne commence par la suite de caractères <balise>, alors on incrémente une variable ($nb) dont la valeur est affichée en fin de traitement.
Exemple 2: Extraction de texte balisé
On cherche à extraire le texte placé entre deux balises. Le nom de la balise sera indiqué en argument de la commande. Nous allons utiliser une expression régulière pour extraire, sur chaque ligne, le texte placé entre les suites de caractères <balise> et </balise>.
#!/usr/local/bin/perl
$rech=$ARGV[0];
while (<STDIN>)
{
if (/<$rech>(.+)<\/$rech>/)
{
print "$1\n";
}
}
La structure de ce programme est identique à celle du précédent, c'est-à-dire que l'on parcourt un fichier en effectuant un test sur chaque ligne. On utilise la variable $ARGV[O] qui est une variable prédefinie. ARGV est en fait un tableau de variables qui contient l'ensemble des arguments passés en ligne de commande. Ainsi $ARGV[O] fait référence au premier argument. On utilise aussi des variables Perl à l'intérieur d'une expression régulière :
if (/<$rech>(.+)<\/$rech>/)
Dans un tel cas I'interpréteur remplace la variable par sa valeur (en considérant que c'est une chaine de caractères). La variable $1 utilisée dans print fait référence au motif reconnu par l'expression régulière entre parenthèses. La variable $_ est une variable prédéfinie: la variable par défaut. Lorsque, pour certaines commandes ou opérateurs (par exemple while), aucune variable n'est précisée bien que ce soit nécessaire, alors c'est cette variable qui est utilisée (d'où son nom).
Exemple 3: Liste des balises
On veut afficher la liste des balises utilisées dans le fichier de travail et les trier par ordre alphabétique. On parcourt le fichier ligne par ligne. Pour chaque ligne: on élimine le texte placé entre les balises; pour chaque nouvelle balise on crée un nouvel élément dans un tableau. Lorsque le fichier a été entièrement parcouru, le tableau contenant la liste des balises est trié, dans l'ordre alphabétique, puis affiché.
Programme
#!/usr/local/bin/perl
while (<>){
chop;
s/>[^<]+</></g;
s/></&/g;
s/ [^&]+&/&/g;
s/[\/<>\t]//g;
@liste=split(/&/);
foreach(@liste){
$ind{$_}++;
}
}
@res=sort keys %ind;
print"\nliste des balises trié : \n@res\n";
La condition du while (<>) permet de faire référence aux fichiers dont les noms sont donnés en argument. Comme pour l'entrée standard (<STDIN>), les lectures de fichiers se font ligne par ligne.
La première partie de la boucle permet de nettoyer la ligne à l'aide de l'opérateur :
$variable =~ s/expression régulière/motif/options
Cet opérateur permet de modifier le contenu de la variable $variable en rempla"ant les suites de caractères couvertes par l'expression regulière par motif. Cet opérateur utilise la variable par défaut. Le nettoyage se fait en quatre temps:
1. Suppression du dernier caractère, en l'occurrence le caractere fin de ligne, à l'aide de la commande chop;
2. Suppression du texte placé entre deux balises.
3. Remplacement de la suite de caractères >< par le caractère %. Le caractère % devient un séparateur de balises (il reste cependant un < en début de ligne et un > en fin de ligne);
4. Elimination des caractères indésirables.
L'instruction @liste=split(/%/) découpe le contenu de la variable par défaut (puisqu'aucun nom de variable n'est indiqué) d'après la valeur d'une expression régulière (ici /%/) et range le contenu dans un tableau
1.7. TDs Perl