Signification de P.e.r.l : Practical Extraction en Report Langage
Traduction Française : Langage pratique d'extraction et de rapport
Créé par Larry WALL en 1987 (premier interpréteur)
Dernière Version Majeure Actuelle : la 5.11
Perl6 est une refonte TOTALE du langage Perl afin de supprimer tous les illogismes, rendre plus pratique l'utilisation du moteur d'expressions rationnelles et en faire un langage fortement typé contrairement à Perl 1 2 3 4 5.Cette refonte est tellement profonde que Perl6 doit être considéré comme un autre langage de programmation à part entière.Perl6 ne fera donc pas l'objet de ce cours.
Sous tout système de la famille des Unix, vérifier que Perl n'est pas déjà installé au moyen de la commande : ` whereis perl `.
Sur mon système renvoie ceci:
perl: /usr/bin/perl /etc/perl /usr/lib/perl /usr/X11R6/bin/perl /usr/bin/X11/perl /usr/local/lib/perl /usr/share/perl /usr/share/man/man1/perl.1.gz
which perl : devrait juste retourner le chemin de l'exécutable.
Si ce n'est le cas une commande de l'installeur exemple sous Debian :
apt-get install perl
sous Redhat:
yum install perl
Sous Mandrake:
urpmi perl
Installera Perl sur votre système.
S'il n'y a toujours pas de Perl, c'est que votre système ne le possède pas par défaut. C'est aujourd'hui devenu rare.
Dans ce cas contactez toujours votre administrateur ou choisissez de compiler perl à partir des sources.
On peut aussi devoir compiler Perl pour pouvoir obtenir un comportement particulier par exemple, le débugage avancé.
Dans ce cas : Il s'agit d'une archive au format .tar.gz ou .tgz ou .tar.bz (bzip2), d'autres formats de compression peuvent être créés.
La procédure de compilation est classique, il faut :
déployer le source
configurer le source
compiler le source
En général in convient lire IMPERATIVEMENT les fichiers README et/ou INSTALL compris dans le source. Il vous indiqueront la procédure qui reste assez simple.
Notez que tout programme source nécessite des librairies de développement qui ne seront pas forcément détectées au moment du ./configure. La compilation échouera et il faudra alors bien regarder quelle en est la raison.
Note : la compilation devrait se faire en tout dernier recours dans un système à base de paquets : linux,rpm/dpkg, et certains autres Unix afin de ne pas trop briser les dépendances de la distribution.
Compiler Perl peut aussi être fait pour des raisons de performances, dans le cas ou certaines applications en ont besoin ou encore si vous faites du packaging.
Il existe plusieurs versions de Perl.
La plus connue et la plus officialisée est ActivePerl développée par la société ActiveState.
On la trouve sur le site ActiveState.com au format .exe ou .msi ou .zip.
Il est préférable de se procurer une version autoextractible au format .exe ou .msi car la version .zip demande l'éxécution d'un script après le déploiement et si on l'oublie, ou si cette procédure est mal faite, peut avoir de graves conséquences sur le fonctionnement de ActivePerl, que vous ne verrons pas forcément.
Avec une version .exe ou .msi l'installation est automatique et ne demande pas de reboot (au moins pour les version récentes de windows).
ActivePerl possède une application graphique et console (un script Perl), "ppm" comme Perl Package Management. Elle permet automatiquement d'installer et de configurer de nouveaux modules à partir d'internet. Nous verrons au troisième cours comment l'utiliser.
Les autres distributions plus ou moins liées au site CPAN pour : Comprehensive Perl Archive Network
qui est un réseau d'archives de bibliothèques et logiciels écrits en langage Perl.
Elles sont souvent moins reconnues car certaines sont en version expérimentales, ce qui permet d'avoir des versions plus avancées (et moins stables) de certains modules parfois.
En voiçi une liste non exhaustive:
vanilla-perl
strawberry-perl
camelbox
djgpp (pour DOS) un peu tombé en désuétude.
on peut tester avec perl -v pour voir la version de Perl installée.
On peut trouver une traduction de la documentation en français sur le site de l'école des mines:
Commencer par :
http://perl.enstimac.fr/DocFr.html
Sur cette URL , on peut télécharger toute la documentation en français aux formats
POD, HTML, PDF et PostScript.
On peut rester sur le site pour la consulter en ligne.
POD c'est quoi?
Et bien c'est justement décrit ici dans la documentation Pod elle-même :
perlpod
- Le format Pod
(plain old documentation), la bonne vieille documentation
Les distributions perl possèdent le programme perldoc qui donne accès à la documentation officielle perlpod (en anglais).
perldoc --help donne les principaux arguments de perldoc.
perldoc <fichier
pod>, exemple
:
perldoc perlre
=> donne la documentation sur les expressions rationnelles de perl.
On a accès aux fonctions natives de perl avec l'argument -f exemple:
perldoc -f grep :
nous dit comment utiliser la commande grep.
Le CPAN: Comprehensive Perl Archive Network est un site de documentation et de stockage d'un nombre impressionnant de modules Perl sur de toutes sortes d'applications.
Note : il existe un module CPAN.pm qui permet de faire des téléchargements et configuration de paquets directement à partir de ce site. Il permet également de publier nos développements.
La première ligne doit indiquer le chemin de l'interpréteur Perl. Sous Windows, ceci est n'est pas vraiment pris en compte car c'est l'association de fichier configuré dans la base de registre du Windows qui le gère. Notez que bien qu'elle commence par # , la première ligne n'est pas un commentaire.
#Un Commentaire commence par #
#La première ligne doit toujours commencer par # mais ...
#! en première ligne n'est pas!!!
# un commentaire mais indique à Perl ou trouver l'interpréteur.
#On affiche avec print auquel il faut ajouter le retour chariot.
print "Bonjour\n";
le ';' indique toute fin d'instruction, affectation ou déclaration.
les variables simples sont des scalaires et commencent pas le signe $ comme en BASIC.
$nom="François";
$age=33;
On peut toujours utiliser printf exactement comme en langage C, bien qu'on ne puisse considérer le typage de la même manière.
printf("Mon nom est %s\nJ'ai %d ans\n",nom,age);
pour passer une commande externe : on peut utiliser la fonction system.
$cmd='dir /s /a *.txt';
system($cmd);
# ou encore, la forme à plusieurs paramètres
system('dir' ,'/s','/a' , '*.txt');
Si l'on souhaite récupérer le flot d'affichage d'une commande, il est préférable d'utiliser les quotes inverse : ` (ALT_GR +7 ) sur le clavier. notez qu'il faut parfois y ajouter la touche espace car dans certains systèmes ce caractère ne s'affiche pas directement.
my @liste_fichiers = `ls -1 -t -r`;
foreach (@liste_fichiers){
...;
}
#un simple scalaire : rechercher perl sous linux
my $perl = `which perl`;
chomp($perl);
print "$perl\n";
Les variables simples sont les scalaires et commencent par '$'.
il existe 4 structures de données spécifiques :
le scalaire noté : $chaine, $n
la liste noté : @liste
le hash noté : %hash
le typeglob, noté : *F
Les typeglobs sont une sorte d'équivalences de symboles un peu comme les macros en C mais assez différents et plus subtils.
Perl est entièrement bâtit sur ces structures simples, et c'est avec l'interaction des ces structures entre-elles que l'ont peut créer des objets de données plus ou moins complexes.
Toute variable perl devrait être déclarée avec l'un des modificateurs de portée existant en Perl et notamment avec my.
voici les mot clés de déclaration possible:
mot clé |
fonction |
exemples |
our ou l'instruction 'use vars' |
déclare une variable globale, cette globalité va au dela du package main. |
our $global_color = 'AAAAAA'; our @global_set; |
local |
rend provisoirement locale une variable ou un identifiant global. |
local @_; local $_; local *F; |
my |
déclare une nouvelle variable, locale au bloc avec visibilité au niveau bloc et de tous les blocs internes. |
my $s=9; { my $s=2; print $s . "\n"; { print $s . "\n"; } } print $s . "\n"; affiche; 9 2 2 9 Car my créer une nouvelle variable par visibilité de bloc. |
my déclare les variables en les rendant accessibles à tout le bloc ET TOUS SES BLOCS INTERNES sauf si une variable de même nom est déclaré dans un sous-bloc, ce que l'on évite en général, mais qui est permis.
my protège ainsi les variables en limitant leur portée lexicale, c'est à dire leur visibilité, au blocs internes, ceci permet plus facilement de les protéger, et de déclarer des variables temporaires à la volée, par exemple des incréments de boucle.
L'instruction:
use strict;
En début de programme rend obligatoire la déclaration des variables avec my, our ou local et force ainsi à définir leur portée lexicale.
our déclare une variable globale : elle sera visible dans tout le code, y compris dans le cas de l'import d'un module.
Il est possible par la suite de rendre une variable globale locale à un bloc {} au moyen du mot clé local mais aujourd'hui ceci est rarement utilisé, disons seulement pour des variables spécifiques à perl et intrinsèquement globales comme $_ par exemple ou encore des descripteurs de fichier : typeglobs ou des opérations sur la table des symboles de perl. en sortant de son bloc, la variable retrouvera la valeur qu'elle avait avant d'entrer dans le bloc.
Les scalaires sont les variables simples de perl elles commencent toujours par le signe '$'. Elles peuvent contenir des nombres de toutes sortes et des chaînes de caractères mais aussi des références que nous verrons par la suite.
my $i=3; #Un nombre
my $str='xxxk34';
my $code='wait for me';
Simple et doubles quotes:
Les simples quotes produisent une affectation stricte
Les doubles quotes permettent l'interpolation.
$nom='marcel';
print 'mon nom est $nom' . "\n";
print "mon nom est $nom" . "\n";
opérateurs d'incrémentation : ++ et +=
$n=2;
print "$n\n";
$n++;
print "$n\n";
n+=7;
print "$n\n";
#opérateurs de concaténation de chaînes : . et .=
my $chaine='mon chapeau';
$chaine = $chaine . ' est joli ';
print "$chaine\n";
for (0 .. 10){
$chaine .= " ya de l'echo "
}
print "$chaine\n";
my $chaine="chaine";
print "|$chaine|\n";
chop($chaine);
print "|$chaine|\n";
my $l="ligne\n";
print "|$l|\n";
chomp($l);
print "|$l|\n";
Comme nous l'avons déjà vu la sortie écran se fait au moyen de print ou de printf.
Il est aussi possible comme en script shell de faire de « l'inline document» ou « heredoc ».
exemple :
print<< "EOF";
Je vous l\'avais dit que ce cours serait long.
cela fait quand-même déjà $n
heures que nous y sommes.
EOF
Notez que si vous mettez écrivez la balise de fin après le print entre quotes, vos variables seront interpolées CAD que ce sera leur contenu qui apparaîtra. Si vous écriver EOF entre simple quotes, tout sera littéral et les variables ne seront pas interpolées.
Notez qu'il est possible de faire de l'"inline document" ou "HereDoc" en affectant une variable, nous verrons cela avec le module DBI pour les requêtes SQL, mais en voici déja un simple exemple:
my $client = 'DUPONT'
my $sexe = 'Monsieur';
my $kg=3;
my $fruit='bananes';
my $message = << "EOF";
$sexe $client a acheté $kg kilos de $fruit
EOF
print $message;
STDIN (que nous avons déjà vu) pour l'entrée, capte ce qui est saisi par l'utilisateur ou un pipe, par exemple :
dir | monprog.pl.
STDIN lira alors le résultat de la commande dir comme suit:
while (<STDIN>)
{
...
}
print et printf écrivent dans STDOUT.
les erreurs sont écrites dans STDERR.
Il faut considérer que l'affichage sur la sortie écran est possible car tous ces flux sont ouverts systématiquement par tout processus de programme Perl au début de son exécution sans que nous ayons à le faire.
Notez que ceci est le cas pour la plupart des langages de programmation.
L'impression dépend fortement du système d'exploitation utilisé et Perl ne peut intervenir que comme composant externe en écrivant dans un périphérique, un flux, un pipe ou une combinaison de ces ressources. Rien n'interdit d'utiliser la commande système pour le faire.
Par contre il existe des et il est même conseillé d'utiliser des Modules qui permettent d'assurer la portabilité de l'impression en Perl, citons pour Windows le module Win32::Printer dont nous parlerons au troisième cours.
création et affectation.
@legumes = ('carotte','choux','navet','salade');
@fruits
= qw(pommes bananes oranges fraises poires);
$fruits[5]='cerise';
@fruits = split(' ', 'pommes bananes oranges fraises poires');
#concaténation
@fruits_et_legumes=(@fruits,@legumes,('citron','pastèque'));
parcourt au moyen de foreach:
foreach my $fruit (@fruits_et_legumes){
print "$fruit\n";
}
parcourt à l'aide des indices:
for my $i (0 .. $#fruits_et_legumes){
print "$fruits_et_legumes[$i]\n";
}
parcourt avec for (test le nombre d'éléments à chaque tour de boucle)
for (my $i=0;$i<@fruits_et_legumes;$i++){
print "$fruits_et_legumes[$i]\n";
}
Les accolades de blocs sont toujours OBLIGATOIRE pour les tests en Perl,
contrairement à la plupart des autres langages.
if (<condition>){
instruction(s);
}
elsif (<condition>{
instruction(s);
}
elsif (<condition>) {
instruction(s);
}
else{
instruction(s);
}
Ce sont les opérateurs habituels qu'on trouve en C et tous les langages qui en découlent:
Symbole |
Signification |
> |
plus grand que |
>= |
plus grand ou égal à |
< |
plus petit que |
<= |
plus petit ou égal à |
== |
égal à |
!= |
différent de |
Symbole |
Signification |
gt |
plus grand que |
ge |
plus grand ou égal à |
lt |
plus petit que |
le |
plus petit ou égal à |
eq |
égal à |
ne |
différent de |
Symbole |
Synonyme Perl |
Signification |
! |
not |
Exprime la négation le contraire, le test est vrai si l'expression qui suit est fausse |
A|B |
or |
A et B son des expressions. vrai si A ou B sont vrais. |
A||B |
|
Vrai si A ou B sont vrais, mais ne teste pas B si A est vrai : Améliore les performances! |
A & B |
and |
Vrai si A ET B sont vrais. |
A && B |
|
Vrais si A ET B sont vrais mais ne teste pas B si A est faux: Améliore les performances. |
Ne perdez pas de vue le fait que parfois, toutes les expressions doivent être exécutées afin d'opérer un traitement dans votre programme, même si elles renvoient faux, et dans ce cas il faudra utiliser la forme simple de | ou de &.
Boucle incrémentale classique.
for(my $i=1; $i<$max;$i++){
...
...
}
Pour les listes on utilise foreach
foreach (@liste){
print "$_\n";
$_ = ($_ . 'x');
$_ .= 'x';
}
On peut aussi utiliser des intervalles
my $max=12;
for (0 .. $max){
print "$_\n";
}
for $n (3 .. 7) {
print "$n\n";
}
Syntaxe |
Exemples |
while (expression){ instructions; } |
while($n > 10) { $n--; } |
do { instructions; } while (expression); |
do { $n--; } while($n > 10); |
do { instructions; } until (expression); |
do { $n++; } until ($n >= 10); |
for (init;condition_arret; action_fin) { instructions; } |
for ($i=0;$i<255;$i++){ printf(« %d %c %o\n »,$i,$i,$i); } |
foreach element (tableau){ instructions; }
|
foreach $one (@liste) { print « $one\n » } |
Next saute un tour de boucle, exemple :
#!/usr/bin/perl -w
my $cherche = '/usr/local';
my $resultat;
open(F,"/etc/fstab");
my @lines=(<F>);
foreach (@lines){
chomp();
next if /^#/;
next if /^\s*$/;
#Les 2 next précédents fond des rejets
my ($part,$dir,$type,$args) = split('\s+');
if ($dir eq $cherche){
$resultat=$_;
last;
}
}
print "$resultat\n";
last met fin à une boucle, exemple :
#!/usr/bin/perl -w
my $cherche = '/usr/local';
my $resultat;
open(F,"/etc/fstab");
my @lines=(<F>);
foreach (@lines){
chomp();
next if /^#/;
next if /^\s*$/;
my ($part,$dir,$type,$args) = split('\s+');
if ($dir eq $cherche){
$resultat=$_;
#La boucle va s'arrèter!!
last;
}
}
print "$resultat\n";
Les instructions de branchement utilisent les labels au moyen d'une instruction qui peut être goto, next ou last. Un label est un simple mot suivi du caractères : On a coutume de les définir entièrement en lettres majuscules.Avec last et next suivis de labels.
Exemple:
#!/usr/bin/perl -w
EXTERIEUR:
for ( $i = 1; $i <= 10; $i++)
{
INTERIEUR:
for ( $j = 1; $j <= 10; $j++)
{
if ( $i * $j == 63 )
{
print "$i fois $j égal 63 !\n";
last EXTERIEUR;
}
if ( $j >= $i )
{
next EXTERIEUR; }
}
}
Elle permet tout simplement de se rendre à une étiquette.
#!/usr/bin/perl
$count = 0;
START:
$count = $count + 1;
if( $count > 4 ){
print "Exiting program\n";
}else{
print "Count = $count, Saut vers START:\n";
goto START;
}
Produit ce résultat
Count = 1, Saut vers START:
Count = 2, Saut vers START:
Count = 3, Saut vers START:
Count = 4, Saut vers START:
Exiting program
Évitez l'abus de goto dans vos programmes et surtout évitez ce genre de choses par exemple:
sckizo.pl
if (condition) {
LABAS:
instruction(s);
}
else {
goto LABAS;
}
(expression) ? (faire ceci) : (faire cela);
Ceci est issu de nombreux langages dont le C à l'origine et a été porté en perl.
La première expression est un test, si le résultat du test est vrai, l'instruction juste après le ? sera exécutée, sinon c'est celle après le : qui sera exécutée.
Avec le conditionnel, on trouve souvent ces instructions abrégées.
Lorsque la condition ou l'instruction est courte, cela permet de raccourcir l'écriture et de se passer des accolades de blocs.
instruction if condition;
next if (condition);
last if (condition);
next until (condition);
last until (condition);
Les hash sont des tableaux dont les indices peuvent être du texte. tout indice est unique et constitue une clé. A chaque clé on associe une valeur.
#déclaration
my %monhash;
#affectation
$monhash{'age'}=33;
$monhash{'nom'}='Jean';
Affectation et déclaration directe
#déclaration
my %monhash;
#affectation
$monhash{'age'}=33;
$monhash{'nom'}='Jean-Yves';
#Relecture avec keys :
foreach my $k (keys %monhash){
print "$k => $monhash{$k}\n";
}
#Relecture avec each
while ( my($k,$v) = each(%monhash)){
print "$k => $v\n";
}
values renvoie la liste des valeurs;
my @valeurs = values %monhash;
Chaque indice constitue la clé d'une valeur.
Les clés sont uniques au caractère prêt (dépendant de la case). : Les clés 'macle' et 'Macle' sont 2 clés distinctes.
Les clés sont indexées : cela signifie que leur accès mémoire est instantané, quel que soit leur nombre.
Après relecture (avec keys) l'ordre des clés est désordonné.
print "Programme indiscret.\n";
$merci="Merci pour ces informations\n";
print "Donnez votre nom : ";
$nom=<STDIN>;
print "Donnez votre age : ";
$age=<STDIN>;
printf("%s\nVous vous appelez %s et vous avez %d ans.\n",
$merci,$nom,$age);
open(FILE,'/chemin/vers/fichier.txt');
Pour contrôler la réussite ou non de l'ouverture, on peut utiliser die et $! :
my $file = '/chemin/vers/fichier.txt';
open(FILE ,$file) or die ''Ne peut ouvrir $file : $!'';
Lecture :
while(<FILE>)
{
print;
}
Fermeture:
close(FILE);
Note : toute fin du programme ferme tous les flux ouverts et lorsqu'on ré-ouvre un même flux avec un nom de fichier différent, le fichier précédent est aussi fermé automatiquement.
Conseil: parfois il vaut mieux fermer un flux 2 fois que pas du tout.
my $cmd = "ipconfig /all";
open(PIPE,"$cmd |") or die "Ne peut ouvrir le pipe sur $cmd : $!";
while(<PIPE>){
...;
...;
print "$_\n";
}
Il convient de ne pas oublier de fermer le pipe:
close(PIPE);
sinon vous risquez un comportement étrange de votre programme avec des bugs subtils.
open(FILE ,''>/chemin/vers/fichier.txt'');
Avec die et $! : pour le contrôle des erreurs:
my $file = '/chemin/vers/fichier.txt'';
open(FILE ,''>$file') or die ''Ne peut ouvrir $file : $!'';
Ecriture:
print FILE ''J\'écris dans le fichier\n'';
print FILE ''Tant que celui-ci est ouvert\n'';
close(FILE);
my $file = 'c:/mesprogrammes/essai.pl';
if ( -d 'c:/mesprogrammes' ) {
if (-e 'c:/mesprogrammes/essai.pl') {
print "Le fichier existe OK";
...
}
else {
print "Le fichier c:/mesprogrammes/essai.pl n'existe pas"
}
}
else {
print "Le répertoire \"c:/mesprogrammes\" n'existe pas ou n'est pas un répertoire.\n";
}
documentation perlfunc : fonction stat
La fonction stat renvoie une liste de 13 champs contenant toutes les informations relatives à un fichier.
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks)
= stat($filename);
on peut choisir seulement les champs que l'on désir comme suit:
@stats=stat($filename);
my ($size,$mtime,$blksize)=@stats[7,9,11]
Ce qui peut être fait en une seule ligne:
my ($size,$mtime,$blksize)=(stat($filename))[7,9,11]
Tout répertoire peut se créer avec la commande mkdir, qui est intégrée à Perl.
opendir(DIR,"c:/perl/lib") or die "Ne peut ouvrir $dir : $!";
my @files=readdir(DIR);
foreach my $fichier (@files){
print ''$fichier\n'';
}
#Notez que readdir renvoyant une liste peut être invoqué par le
#foreach directement
sans la liste temporaire @files
foreach my $fichier (readdir(DIR)){ .. }
my $scalaire = 'du texte';
my $ref_scalaire=\$scalaire;
déréférencement:
print $$scalaire . "\n";
Pour une liste:
my $ref_liste = \@liste;
foreach (@{$ref_liste}){
print "$_\n";
}
Pour un hash
my %h = ( age => 30,
prenom => 'Jean',
nom => 'DURANT');
my $ref_hash=\%h;
foreach my $one (keys %{$ref_hash}){
print "$one => $ref_hash->{$one}\n";
print "meme chose : $one => $$ref_hash{$one}\n";
}
Voiçi maintenant un exemple de création de hash, et liste anonyme:
#!/usr/bin/perl -w
use strict;
#hash anonyme
my $h = {};
print $h . "\n";
$h->{toto}=1;
$h->{titi}=33;
print Dumper($h);
#tableau anonyme
my $l= [];
print $l . "\n";
push(@$l,qw(toto titi tata momo lolo coco));
foreach my $one (@{$l}){
print "$one\n";
}
http://perl.enstimac.fr/DocFr/perlref.html
http://perl.enstimac.fr/DocFr/perllol.html : liste de listes
perldsc
- Livre de
recettes des structures de données en Perl
Perl définit possède un nombre impressionnant de variables prédéfinies, elles permettent de rendre beaucoup de choses implicites et rendent le langage beaucoup plus puissant.
D'autres permettent de donner des informations, ou de modifier le comportement par exemple '$/' configure le séparateur des enregistrements en entrée.
En voici les principales:
Variable |
Nom(s) long |
Description |
$_ |
$ARG |
C'est la variable par défaut: Dans une boucle foreach ou lors du parcourt d'un fichier, c'est la ligne courante, ou si l'on veut, l'élément en cours, lors de l'appel d'une fonction sans paramètres, $_ est envoyé par défaut. - Lors de l'affichage avec print : print; == print $_; et beaucoup comme dans beaucoup d'autres cas. |
$. |
$NR $INPUT_LINE_NR |
Lors de la lecture d'un fichier donne le numéro de la ligne courante. |
|
|
Le séparateur des enregistrements en entrée. Notez que si l'on fixe celui-ci à une taille fixe le fichier est lu par bloc et si l'on le fixe à undef, le fichier est lu entièrement d'un seul coup autrement dit tout le fichier sera contenu dans $_ dès la première lecture comme s'il le fichier n'avait qu'une seule ligne. |
|
|
Permet l'affectation d'une chaîne de caractères qui est insérée à chaque sortie avec print |
|
|
Permet l'affectation d'une chaîne de caractères qui est ajoutée automatiquement à chaque valeur distincte sortie avec print sous forme de plusieurs valeurs distinctes séparées par des virgules. |
|
|
Permet l'affectation d'une chaîne de caractères qui est ajoutée automatiquement à chaque valeur distincte sauf la dernière, quand une liste ou un tableau dans une chaîne de caractères est sortie interpolée avec print. |
|
|
Quand
cette variable est fixée sur une valeur différente
de |
|
|
Contient un message explicitant la dernière erreur système produite. Cette variable est souvent utilisée avec die() par exemple afin d'indiquer la raison de l'échec d'une opération système. |
|
|
Après un eval() qui n'a pas réussit, contient une valeur différente de nul. Cela permet de savoir si l'éval à réussit. |
$$ |
$PID |
Processus courant |
$0 |
$PROGRAM_NAME |
Nom du programme courant |
$^X |
$EXECUTABLE_NAME |
Nom de l'interpréteur courant |
$] |
$PERL_VERSION |
Numéro de la version de Perl |
$^T |
$BASETIME |
Contient la dateheure (au format epoq) à laquelle le script a été lancé. |
$^0 |
$OSNAME |
Contient le nom du système d'exploitation. |
Notez que je n'ai pas inclus les variables prédéfinies relatives aux expressions rationnelles.
Nous les verrons lors de l'étude du chapitre.
Note : pas de nom long.
Nom |
Description |
@_ |
A l'intérieur d'une fonction perl (sub), contient la liste de ses arguments. En principe, chaque argument ne peut être modifié mais ils peuvent être supprimés notamment par la fonction shift(). |
%ENV |
Contenu des variables d'environnement, exemple $ENV{PATH} contient le PATH. |
%SIG |
Contient le gestionnaires des signaux. |
@ARGV |
Contient les paramètres de la ligne de commande. |
@INC |
Contient les chemins configurés ou Perl va rechercher les modules auquel il a accès. |
@ISA |
Dans une classe (un module) , est utilisé pour le faire hériter d'autres classe. Il suffit d'insérer chaque classe dans la liste @ISA. |
@EXPORT |
Dans un module, tout nom symbole inséré (scalaire,liste,hashs,fonctions) sera rendu accessible au script final. |
@EXPORT_OK |
Dans un module, tout nom symbole inséré (scalaire,liste,hashs,fonctions) sera rendu accessible au script final, mais seulement si le script final l'importe. |
Vous trouverez une liste plus complète dans la documentation officielle de Perl :
perlvar
- Variables
prédéfinies en Perl
Et sur ce site avec des exemples simples :
http://fr.selfhtml.org/cgiperl/langage/predefini.htm
Le but étant de connaître les plus importantes, $_ et @_ sont incontournables.
Issu des mathématiques des langages formels des années 45/50, elles permettent d'analyser formellement du texte.
Le principe est la création de motifs d'expressions rationnelles au moyen de symboles élémentaires suivis eux-même de symboles de répétitions; les seconds complétant les premiers et ce chapitre contient deux tableaux les décrivant.
La documentation Perl décrit les expressions rationnelles dans ces 4 fichiers, il faut bien entendu commencer par le plus simple et ceci vient en complément du cours.
perlrequick
- Les
expressions rationnelles Perl pour les impatientsperlre
- Les
expressions rationnelles en Perlperlreref
- La
référence pour les expressions rationnelles en Perlperlretut
- Tutoriel
des expressions rationnelles en Perl
Ce chapitre peut sembler abstrait et/ou trop théorique si vous n'avez jamais fait d'expressions rationnelles. Attendez d'arriver a la fin du point 4 , point ou vous devrez mettre la théorie en pratique par vous-même, et n'hésitez pas à poser vos questions à ce moment.
Ils permettent de définir un caractère et un seul à un emplacement donné dans la séquence du motif. Ce caractère pouvant être abstrait comme le début de ligne ^ ou sa fin $. Il peut être aussi indéfini comme '.' ou faire partie d'un groupe (range) que l'on peut aussi appeler classe, exemple : [A-Za-z] défini une lettre de l'aphabet majuscule ou minuscule.
Notez que La norme POSIX définit en plus, des classes prédéfinies permettant de construire des ensembles courants et utiles sans écrire une suite interminable de lettre entre crochets par exemple [:alnum:] définit un ensemble aphanumérique. Notez les ':' avant et après. Pour des raisons de simplicité, je n'ai pas souhaiter les décrire içi.
Vous trouverez l'ensemble de ces classes dans la documentation Perl traduite :
perlreref - La référence pour les expressions rationnelles en Perl
et se rendre à la section "CLASSES DE CARACTERES".
Dans le tableau ci-dessous les principaux symboles à connaitre.
Symbole |
Description |
^ |
Représente le début de la ligne. |
$ |
Représente la fin de ligne. |
. |
Un caractère quelconque. |
[AdE94] |
L'un des caractères entre crochets. |
[0-9] |
Un chiffre. |
[a-zA-Z] |
Une lettre de l'alphabet majuscule ou minuscule. |
[^ ] |
Dans
une classe (Entre crochet) signifie l'exclusion de tous les
caractères qui suivent. |
(..) |
Un regroupement Destiné à utiliser les caractères génériques définis par la suite, ou les variables réservées représentant le regroupement, ce qui le précède ou ce qui le suit. |
(A|B[|C]...) |
A, B et C étant des mots simples, des expressions, des chaînes strictes ou des motifs d'expressions rationnelles pouvant déjà contenir des regroupements (). le symbole | signifie OU et l'expression sera considérée comme vraie si A ou B ou C est vrai. Le nombre de membre n'est pas limité, il convient cependant de ne pas mettre trop de membres complexes avec des expressions rationnelles dans chaque membre car cela rend vite très floue le sens global de l'expression rationnelle. Le | convient mieux pour des mots simples. Par exemple: if (/^\s*Choice(Hour|Min|Sec) = new Choice\(/){ ...; } |
Afin de constituer le motif, chaque caractère qui est définit au moyen d'un symbole ou d'une classe décrit dans le tableau précédent peut être répété un certain nombre de fois. Là encore la symbolique peut décrire un nombre abstrait de répétitions: * signifie entre 0 et x fois, + entre 1 et x fois, etc...
Notez que toutes ces répétitions peuvent aussi s'appliquer sur des regroupement entre parenthèses constitués de suites concrètes lettrées et/ou des motifs même d'expressions rationnelles plus ou moins complexes.
Symbole |
Description |
+ |
Vrai si le caractère, la classe ou le symbole ou le regroupement entre parenthèses qui précèdent sont répétés au moins une fois. |
* |
Vrai si le caractère, la classe ou le symbole ou le regroupement entre parenthèses qui précèdent sont répétés 0 ou plusieurs fois . |
? |
Le caractère, la classe ou le symbole ou le regroupement entre parenthèses qui précèdent sont facultatifs, Ils peuvent être là ou pas. |
{n} |
(n est un nombre)Vrai si le caractère, la classe, le symbole ou le regroupement entre parenthèses qui précèdent sont répétés exactement n fois. |
{n,} |
(n est un nombre)Vrai si le caractère, la classe, le symbole ou le regroupement entre parenthèses qui précèdent sont répétés au moins n fois. |
{,m} |
(n est un nombre)Vrai si le caractère, la classe, le symbole ou le regroupement entre parenthèses qui précèdent sont répétés au plus m fois. |
{n,m} |
Vrai si le caractère, la classe, le symbole ou le regroupement entre parenthèses qui précèdent sont répétés entre n et m fois. |
Les deux tableaux précédents décrivent l'essentiel afin de pouvoir construire des motifs plus ou moins complexes.
En perl le motif est entouré des caractères / en général mais il peut être remplacé par un autre pour convenance.
exemple d'un motif de base avec recherche dans $_
foreach (@liste){
unless (/^\s*$/)
{
print "$_\n";
}
}
Quant la recherche se fait sur une variable : on utilise = suivis du tilde : ~
foreach my $ligne (@liste){
unless ( $ligne =~ /^\s*$/){
print "$_\n";
}
}
Le séparateur peut changer pour convenance, on place la lettre (m : match) devant dans ce cas:
my $full_filename='/usr/local/bin/codeblocks';
if ($full_filename =~ m#^/([^/]+/){3}([^/]+)#){
$file=$2;
}
#dans une boucle de lecture de fichier : réjection
while (<>){
#saute la ligne si elle contient une suite d'espace éventuels,
#suivis de 3 '-' ou plus, ces lignes ne seront pas affichées
next if /^\s*-{3,}/;
print "$_\n";
}
s/<expression_rationnelle>/<remplacement>/[modificateur]
L'opérateur de substitution est s, il possède 3 séparateurs '/' dans l'exemple ci-dessous. Le motif d'expression rationnelle se trouve entre le premier et le second séparateur et par quoi le remplacer entre le second et le troisième. Dans notre exemple, le remplacement est vide, ce qui revient à supprimer la partie matchée par le motif.
Note : La fin de la substitution peut être suivie d'un modificateur (une lettre) qui va comme son nom l'indique modifier le comportement de l'instruction , dans un permier temps, nous ne verrons que le modificateur 'g' dans ces exemples qui indique à perl de substituer toutes les occurrences de la ligne car par défaut seule la première est substituée.
Voici quelques exemples de substitution:
while (<>){
#supprime toute suite de nombre en début de ligne
s/^([0-9]+)//;
#change le premier 'e' en 'E' dans la ligne.
s/e/E/;
#Change tous les bateau en chapeau dans la ligne
#(notez le modificateur 'g' a la fin du motif)
s/bateau/chapeau/g;
#changement des '/' en '\' , les '\' doivent être protégés par l'antislash.
s/\//\\/g;
#Strictement identique,
#Mais pour des raisons de bon sens, le séparateur peut-être est changé en ','
# l'antislash étant un méta-caractère, il doit être protégé par l'antislash-lui même, c'est
#pourquoi il est doublé, le fait de changer le séparateur rend le motif beaucoup plus lisible
#dans ce cas
s,/,\\,g;
}
$full_filename = '/usr/local/bin/codeblocks';
$full_filename =~ s,^/([^/]+/){3},,;
#substitue afin de ne garder que 'codeblocks'
La fin d'un motif de match ou de substitution peut être suivie d'un ou de plusieurs modificateurs qui peuvent changer considérablement l'action opérée.
Voiçi la pluspars des modificateurs utilisés et leur signification:
modificateur |
Rôle |
i |
Permet de faire une recherche insensible à la case (majuscules/minuscules) |
e |
Seulement dans une substitution, au lieu de substituer directement, évalue la partie de remplacement comme une expression perl qui peut contenir des fonctions et c'est le résultat de cette expression qui va alors fournir le remplacement. |
g |
Dans le cas d'une substitution, permet de faire une recherche de toutes les occurrences du motif recherché sans s'arrêter à la première. Toutes les occurrences de la chaîne qui correspondantent au motif subiront le remplacement. |
m |
Permet de traiter les chaînes multilignes : les caracteres ^ et $ reconnaissent alors n'importe quel début ou fin de ligne plutôt qu'au début ou à la fin de la chaîne. |
s |
Les modificateurs |
x |
|
voiçi un exemple de regroupement, extractions des champ d'une date et heure:
#!/usr/bin/perl -w
#exemple de regroupements
my $str="12/02/2008 10:33:42";
if ( $str =~ m{([0-9]{2})/([0-9]{2})/([0-9]{4})\s([0-9]{2}):([0-9]{2}):([0-9]{2})}){
#On retrouve les parties machées dans les variables spéciales $1, $2 ... $<n>
my ($jour,$mois,$annee,$heure,$minute,$seconde) = ($1,$2,$3,$4,$5,$6);
print join("\n",($jour,$mois,$annee,$heure,$minute,$seconde)) . "\n";
}
Ici les regroupements concernent des chiffres, on récupère chaque regroupement dans les variables $1 $2 $3 , et dans l'ordre des parenthèses ouvrantes.
Ceci est très pratique pour faire des extractions spécifiques. Notez que les regroupements peuvent être imbriqués.
Perl définit des variables spéciales qui s'affectent automatiquement lorsqu'une expression rationnelle est exécutée.
En voici la liste et le rôle de chacune:
Variable |
Nom long |
Fonction |
$& |
$MATCH |
La partie matchée d'une expression rationnelle. |
$` |
$PREMATCH |
Ce qui se trouve avant l'expression rationnelle. |
$' |
$POSTMATCH |
Ce qui se trouve après l'expression rationnelle. |
$(n) |
n est un nombre |
Le énième regroupement matché d'une expression rationnelle. |
$* |
$MULTILINE_MATCHING |
Pour gérer le matching sur plusieurs lignes mais il est devenu obsolète et grandement préférable d'utiliser le flag 's' : m//s |
@- |
@LAST_MATCH_START |
Donc, après
une recherche de motif dans $_, $& coïncide avec Ce
tableau contient les positions des débuts des sous-chaînes
correspondant aux groupements de la dernière
recherche de motif réussie dans la portée dynamique
courante. Après une recherche sur une variable $var :
|
@+ |
@LAST_MATCH_END |
Ce
tableau contient les positions [offsets] des fins des sous-chaînes
correspondant aux groupements de la dernière recherche de
motifs réussie dans la portée dynamique courante.
|
ATTENTION : ces variables sont affectée lors de l'exécution de l'expression rationnelle, mais dites-vous bien qu'elle correspondent à la dernière expression rationnelle exécutée. Cela signifie que vous toute nouvelle expression rationnelle écrasera la dernière valeur.
Une forme avec le flag e par exemple exécute une expression dans la substitution et si cette expression appelle une sub qui fait elle-même du matching, vos variables seront modifiées par la dernière expression rationnelle rencontrée.
De plus si vous ne testez pas la réussite (ou non) de votre expression rationnelle (au moyen de if), vous aurez peut-être quelques-chose dans $& , $1 and co, mais cela ne prouve pas que votre matching aura réussit: ce seront les dernières valeurs affectées par la dernière expression rationnelle exécutée 20 lignes plus haut par exemple.
A ce titre, voiçi par exemple ce qu'il ne faut pas faire:
while (<FILE>){
chomp;
/mon bateau, le ([\w]+)/; #recherche le nom du bateau
$nom_bateau = $1;
}
Car si l'expression échoue, rien ne dit que $1 sera affectée, pire $1 peut être affectée par une expression rationnelle lancée 100 lignes plus haut et contiendra n'importe quoi.
if vaut mieux écrire ceci:
while(<FILE>){
chomp;
my $mon_bateau;
if (/mon bateau, le ([\w]+/){
$nom_bateau = $1;
}
perlfunc
- Fonctions
Perl prédéfinies
Notez que ce fichier est gros car il contient la description de toutes les fonctions perl prédéfinies c'est à dire compilées dans l'interpréteur, et ne faisant appel à aucune librairie externe. Il convient donc d'y faire une recherche textuelle dans ce gros fichier afin d'y trouver ce que l'on cherche.
Split éclate une chaîne de caractères d'après un motif d'expressions rationnelle.
split([<motif>,[chaîne]],[limite]);
Elle retourne sous forme de liste, toutes les occurrences comprises autour des séparateurs trouvé.
A noter que les champs vides en dernier sont supprimés. Ceci peut être contourné en imposant un nombre d'éléments au tableau retourné au moyen du troisième paramètre : limite.
Limite peut aussi limiter le nombre de champs lorsqu'il y en a trop pour nos besoins.
Dans le cas ou aucun champ n'est vide, le nombre des éléments sera égal aux nombre de séparateur +1 (règle des poteaux et des intervalles).
La chaîne par défaut est $_ et le séparateur par défaut est une suite de blanc correspondant au motif suivant /^\s+$/
Split a en principe un tableau comme lvalue (valeur de gauche avant le =) mais si l'on lui donne un simple scalaire, il renvoie le nombre d'éléments qu'il a trouvé dans la chaîne. Ce qui peut être utile pour les compter.
exemples:
#!/usr/bin/perl -w
while (<>){
chomp;
@res=split(/\s+/);
#compte le nombre d'éléments.
my $nb_elements=split(/\s+/,$_);
my $n=0;
foreach my $one (0 .. $nb_elements){
# opère un traitement pour chaque champs éclatés.
print "$res[$one] element $one , $nb_elements total.\n";
}
}
while (<>){
my ($nom,$age) = split(';',$_,2);
print "$nom;$age\n";
}
Join fait l'inverse de split : il prend un tableau et constitue une chaîne de caracteres en sépararant chaque élément du tableau par le séparateur donné en argument.
my $file='monfic.csv';
open (CSV,$file) or die "Ne peut ouvrir $file : $!";
while (<CSV>){
chomp();
my ($nom,$prenom,$age) = split(';',$_,3);
#passe en majuscules la première lettre du prénom
$prenom =~ s/^([a-z])/uc($1)/e;
#passe en majuscules toutes les lettres du nom
$nom =~ tr/[a-z]/[A-Z]/;
#reconstitue la chaîne initiale
$_= join(';',($nom,$prenom,$age)) . "\n" ;
#Affiche la chaîne initiale
print;
}
La méthode officielle pour le faire est d'utiliser le débuggeur ainsi:
perl -d -e 1
Ainsi vous serez façe à un shell et toutes les commandes perl que vous tapez seront exécutées à chaque saisie de la touche <ENTREE>.
Il n'est toutefois pas très compliqué de réaliser ce genre de programme étant donnée la puissance de Perl.
Néammoins, notez qu'il n'est pas simple d'obtenir un interpréteur sûr et de qualité.
psh : un shell perl dans le sens de permettre l'exécution de commandes systèmes en passant par le shell.
perlconsole: un programme sophistiqué permettant un vrai mode interactif, à notez que ce programme utilise des modules perl externes pour fonctionner.
Il en existe d'autres, dont certaines sous forme de librairies plus ou moins sophistiquées.
Note: Il est étrange que Perl n'ai pas un mode natif pour ce genre de chose comme python par exemple.
L'option -d de Perl est surtout utilisée pour le débogage.
perl -d monprog.pl
permet de lancer monprog.pl en mode débogage. Cela signifie que vous verrez un shell vous invitant à entrer des commandes.
Ainsi, votre programme ne sera lancé que si vous le demandez et vous pourrez faire un tas d'action de contrôle et d'analyse sur l'exécution de votre programme.
Les commandent consistent en une seule lettre suivie de la touche <ENTRER>.
La première commande que vous pouvez lancer est 'h' qui vous affichera une description de l'ensemble des commandes existantes et leur action.
Notez qu'utiliser le débogeur ainsi est assez drastique. Néanmoins ce n'est pas une mauvaise chose car avec de l'habitude vous trouverez vos repères et vous n'aurez besoin de rien d'autre.
Il existe des interfaces (notamment en python) qui permettent de rendre cette utilisation plus conviviale, mais c'est une nécessité supplémentaire que vous n'aurez pas toujours à votre portée.