Expressions régulières - Variable $_ |
||
|
Rassure-toi il ne s'agit que d'une introduction aux expressions régulières ! D'une façon générale comme pour les notions élémentaires on ne dira pas tout... mais on en dira un peu plus. Pour tout savoir sur un sujet il faut consulter la doc officielle. Mais revenons à nos "expressions régulières". Pour te donner une idée de leur importance, figure-toi que j'ai lu quelque part que "L'une des possibilités les plus utiles en perl (sinon LA plus utile) était la puissance de manipulation des chaînes de caractères." Ce qui confère au langage perl cette puissance, ce sont les expressions régulières. Tu trouveras également le terme "expressions rationnelles" qui est une autre manière de traduire l'anglais "regular expression". Une expression régulière est une sorte de mélange entre un mini-programme et un mini-traitement de texte. Elle est contenue par des slash "/", et l'application à une chaîne de caractères se fait grace aux opérateurs =~ et !~ . Il existe des expressions régulières d'une complication, (et d'un hermétisme !) épouvantable. Aussi, attention ! On peut faire beaucoup de choses avec, mais également passer de longues heures à la mise au point et poser des casses-têtes effroyables à ses collègues. Ce qui est certain c'est qu'il faut documenter et faire des tests complets, en prenant bien soin des limites (champs vides et maxi) car bien souvent ce que l'on a péniblement écrit ne fait pas du tout ce que l'on croyait. Pour ma part ayant déjà travaillé avec des expressions régulières (et m'étant délecté avec), je serai assez tenté de croire qu'un "vrai perliste" se fait un point d'honneur à utiliser les plus complètes (donc les plus compliquées !) possibles... Mais je suis certainement médisant en pensant cela... :o) | ||
|
Pour l'instant on va commencer simple. D'abord l'opérateur =~ Il applique l'expression régulière de droite sur la chaîne de gauche. Par exemple:
Faisons de suite un sort à l'opérateur contraire !~ Pour reprendre notre exemple : $phrase!~/chat/ sera vrai si la phrase NE contient PAS la chaîne "chat". Attention les expressions régulières sont sensible à la casse : chercher "CHAT" n'est pas pareil que chercher "chat". |
||
La variable $_ ou $ARGC'est une variable spéciale prédéfinie : la variable de stockage par défaut. C'est aussi un espace de travail utilisé dans les recherches de motifs. Dans certain cas l'omission est autorisée et permet une simplification de l'écriture. Par exemple les expressions suivantes sont équivalentes :
Voici quelques endroits où $_ s'utilisera de façon implicite :
|
||
La recherche de motifs (pattern) |
||
|
Détaillons l'expression de recherche m/..../ (Attention on va souffrir un peu... :o)) Syntaxe générale : m/PATTERN/cgimosx
|
||
^ et $ début et fin de lignes/chaînes
$_="Demain j'irai a la peche aux moules";
if (/^Demain/) {print "OK\n";} else {print "KO\n;"}
if (/peche/) {print "OK\n";} else {print "KO\n;"}
if (/^peche/) {print "OK\n";} else {print "KO\n;"}
OK. La chaîne commence bien par DemainOK. La chaîne contient bien 'peche' KO. Effectivement la chaîne ne commence pas par 'peche'
if (/moules$/) {print "OK\n";} else {print "KO\n;"}
if (/peche/) {print "OK\n";} else {print "KO\n;"}
if (/peche$/) {print "OK\n";} else {print "KO\n;"}
OK. La chaîne se termine bien par moulesOK. La chaîne contient bien 'peche' KO. Effectivement la chaîne ne finit pas par 'peche' |
Dans les exemples remarque le placement de ^ et $ par rapport à la chaine recherchée. | |
. * + ? présence de caractères
$l="Lundi j'irai a la peche aux moules";
$m="Mardi j'irai a la peche aux moules";
$v="Vendredi j'irai ala peche aux moules";
if ($l=~/^...di/) {print "OK\n";} else {print "KO\n;"}
if ($m=~/^...di/) {print "OK\n";} else {print "KO\n;"}
if ($v=~/^...di/) {print "OK\n";} else {print "KO\n;"}
OK. La chaîne commence bien par trois caractères suivi de diOK. Idem KO. Pas là car après 'Ven' on ne trouve pas 'di'
if ($l=~/a *la/) {print "OK\n";} else {print "KO\n;"}
if ($m=~/a *la/) {print "OK\n";} else {print "KO\n;"}
if ($v=~/a *la/) {print "OK\n";} else {print "KO\n;"}
OK. La chaîne contient bien 'a' et 'la' séparés par un blancOK. La chaîne contient bien 'a' et 'la' séparés par plusieurs blancs OK. La chaîne contient bien 'a' et 'la' séparés par rien du tout
if ($l=~/a +la/) {print "OK\n";} else {print "KO\n;"}
if ($m=~/a +la/) {print "OK\n";} else {print "KO\n;"}
if ($v=~/a +la/) {print "OK\n";} else {print "KO\n;"}
OK. La chaîne contient bien 'a' et 'la' séparés par un blancOK. La chaîne contient bien 'a' et 'la' séparés par plusieurs blancs KO. La chaîne contient bien 'a' et 'la' mais séparés par rien du tout et comme il faut au moins un blanc de séparation....
if ($l=~/a ?la/) {print "OK\n";} else {print "KO\n;"}
if ($m=~/a ?la/) {print "OK\n";} else {print "KO\n;"}
if ($v=~/a ?la/) {print "OK\n";} else {print "KO\n;"}
OK. La chaîne contient bien 'a' et 'la' séparés par un blancKO. La chaîne contient bien 'a' et 'la' mais séparés par plusieurs blancs or il n'en faut qu'un ou pas du tout... OK. La chaîne contient bien 'a' et 'la' séparés par rien du tout |
Alors à ton avis que représentent
| |
La substitution de caractères s/..../..../ |
||
|
Syntaxe générale : s/PATTERN/CIBLE/egimosx
|
||
{n} {n,} {n,m} présence de caractères (suite)
#!usr/bin/perl -w
$p1="brrrrr! il fait un froid de canard";$p0=$p1;
$p1=~s/r{2}//;
print "avant:$p0\napres:$p1\n";
avant:brrrrr! il fait un froid de canard
apres:brrr! il fait un froid de canard
Et avec l'option g (globale) on obtient :
$p1=~s/r{2}//g;
avant:brrrrr! il fait un froid de canard
apres:br! il fait un froid de canard
|
Tu remarqueras l'utilisation d'une chaine vide comme CIBLE. | |
#!usr/bin/perl -w
$p1="brrr! il fait un froid de canard";$p0=$p1;
$p1=~s/r{4,}//;
print "avant:$p0\napres:$p1\n";
avant:brrr! il fait un froid de canard
apres:brrr! il fait un froid de canard
|
Normal, on veut enlever 4 fois le caractère r et il n'y en a que 3...Rajoutes en un, puis deux, puis etc... et teste. | |
#!usr/bin/perl -w
$p1="brrr! il fait un froid de canard";$p0=$p1;
$p1=~s/r{2,4}//;
print "avant:$p0\napres:$p1\n";
avant:brrr! il fait un froid de canard
apres:b! il fait un froid de canard
|
||
[...] Classes de caractèresLes crochets [] sont utilisés pour assortir n'importe lequel des caractères qu'il contiennent. A l'intérieur des crochets, "-" signifie : entre et "^" signifie : pas. Par exemple:
#!usr/bin/perl -w $v="-1a457bd012";$w=$v; $v=~s/[+\-0-9]/ /g; $v=~s/[^ ]/^/g; print "$w\n$v\n"; -1a457bd012 ^ ^^
|
Le premier substitute transforme tout ce qui est + - ou chiffre par un blanc et le deuxième tout ce qui n'est pas un blanc par ^ | |
La traduction ou translitération tr/..../..../ |
||
|
Syntaxe générale : tr/liste_recherche/liste_remplacement/cds
|
||
Quelques exemples :
$ph =~ tr/A-Z/a-z/; # tout en minuscule
$cnt = tr/*/*/; # compte les étoiles
# dans $_
$cnt = $sky =~ tr/*/*/;# compte les étoiles
# dans $sky
$cnt = tr/0-9//; # compte les chiffres
# dans $_
tr/a-zA-Z//s; # bookkeeper -> bokeper
($HOST = $host) =~ tr/a-z/A-Z/;
tr/a-zA-Z/ /cs; # remplace tous les
# non alphanumériques
# par un seul espace
tr [\200-\377]
[\000-\177]; # efface le 8ème bit.
|
||