(Voir la section perlre du manuel de Perl)
Les expressions régulières sont des caractères permettant de coder
n'importe quelle entité écrite appartenant à un ensemble (ex:
les décimales, les majuscules, les mots commencant par z ou une
minuscule, etc...). Elles sont largement utilisées par les
développeurs UNIX et sont implémentées dans des commandes telles que
awk
, sed
, ed
, vi
. Même le langage C dispose d'une
librairie d'expressions régulières.
Le principe de ces caractères est de construire un masque codant l'entité cible. Ensuite chaque séquence de caractères est comparée au masque. S'il y a correspondance, la séquence appartient à l'ensemble de l'entité.
Ce mécanisme permet de faire des remplacements de chaînes de caractères dans un fichier sans savoir ou sont placées les chaînes à remplacer. Il permet d'extraire des informations sans en connaître la position dans un ou plusieurs fichiers. C'est de loin le meilleur outil d'extraction et de traitement d'informations dans un fichier et c'est pourquoi Perl l'utilise.
Illustrons l'usage des expressions en codant l'ensemble de tous les mots à caractères minuscules.
[a-z]
[ ] permet de définir un ensemble de caractères. Le
caractère -
signifie que l'ensemble contient la lettre a, b, c,
... ou z. On aurait pu écrire:
[abcdefghijklmnopqrstuvwxyz]
alain appartient appartient à l'ensemble des mots composés
de lettres minuscules. Par contre Alain non, car le mot contient
A
.
De manière générale une E.R. est préfixée et suffixée du
caractère /
.
/[a-z]/
Voici une rapide description de quelques caractères d'expression régulières.
. # n'importe quel caractère alphanumérique et # d'espacement. + # fait correspondre au moins 1 fois ou plusieurs ce # qui précède ? # 0 ou au plus 1 caractère de ce qui précède # a? permet de faire correspondre '' ou 'a' * # 0 ou plusieurs caractères de ce qui précède # a* peut faire correspondre '', 'a', 'aa', 'aaa', etc... [] # un intervalle [^] # un complément ^ # qui commence par $ # qui finit par () # Définit un groupe de caractères réutilisable | # ou
Perl étend le jeu de caractères des expressions.
\s # n'importe quel caractère d'espacements \S # le complément de \s
Perl permet de modifier le traitement des chaînes par des
options, en passant une ou plusieurs lettres après le
/
final de l'E.R :
i # les majuscules sont traitées comme des minuscules m # traite la chaine de caractères commes si elle était # constituée de plusieurs lignes s # traite la chaine comme si elle était sur une seule # ligne
Deux opérations sont principalement utilisées par les expressions régulières. La substitution et le pattern matching (la mise en correspondance).
s/source/target/options
s
signifie substitution. / est le séparateur
d'expression. Si une chaîne lue correspond à source elle
est remplacée par target. options agit sur le nombre de
substitutions. Si
g
est utilisé alors toutes les chaînes
de la ligne lue correspondant à source sont remplacées (g
pour global). e
permet d'évaluer target. Ainsi pour
convertir un fichier texte en un fichier ne comportant que des
majuscules on aurait le code suivant (fichier uc.pl
):
#! /usr/bin/perl while(<>) { s/^(.*)$/uc($1)/e; $_; }
On peut tester cette opération de la façon suivante:
$ uc.pl /etc/passwd
Le fichier /etc/passwd s'affiche avec uniquement des caractères majuscules.
Remarque: la première ligne #! /usr/bin/perl
permet de spécifier au shell quelle commande il doit lancer pour
interpréter le contenu du fichier uc.pl. .pl
est le suffixe
standard des fichier scripts Perl.
Le programme wc.pl suivant effectue le meme travail que la commande
unix, à savoir comptabiliser le nombre de caractères, de
lignes et de mots d'un fichier donné en argument (fichier wc.pl
):
#! /usr/bin/perl # Retourne le nombre de mots dans une ligne par mot on comprendra tous # ce qui n'est pas 'espace'. sub compte_mot { my($ligne) = @_; $ligne =~ s/\s+/ /g; my(@tab) = split( /\s/, $ligne); $#tab; } sub compte_ligne { my($ligne) = @_; return 1 if $ligne !~ /^\s*$/; } sub compte_char { my($ligne) = @_; $ligne =~ s/\s//g; length($ligne); } sub main { my($mots, $lignes, $chars); while(<STDIN>) { $mots += compte_mot($_); $chars += compte_char($_); $lignes ++ if compte_ligne($_); } print "$ARGV[0]: w = $mots, l = $lignes, c = $chars\n"; } main;
Exemple d'utilisation :
$ wc.pl /etc/passwd
Remarque: <STDIN> (equivalent à <>) est le flux de l'entrée standard. <STDOUT> et <STDERR> ceux de la sortie standard et d'erreur.