Vous êtes sur la page 1sur 29

1 http://cyberzoide.developpez.

com Le CyberZode Qui Frtille


Expressions rgulires
en PHP
Hugo Etivant
Dernire mise jour : 15 avril 2004
2 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Prsentation
Tout programmeur sest dj vu oblig de traiter des chanes de caractres.
Sur le web, les pages elles-mmes, les donnes transmises aux scripts et
celles provenant des bases de donnes sont des chanes de caractres quil
faut traiter, analyser, corriger Chose ardue et quasi-impossible sans
lutilisation dun formidable outil que sont les expressions rgulires (dites
aussi expressions rationnelles).
Nous nexpliquerons pas lalgorithmique sous jacente trs complexe (machines
tats, automates, graphes, rcursivit) mais illustrerons seulement son
utilisation via les fonctions de PHP.
On utilisera par la suite le terme regex terme emprunt langlais pour
dsigner une expression rgulire.
A noter que les fonctions PHP dont il est question ici sont conformes la
norme POSIX et hrit du langage Perl.
3 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Motifs
Une regex sapparente une expression mathmatique, car on y trouve des
oprateurs, des valeurs et des variables.
Les regex permettent de se lancer la recherche de motifs dcrits par la
combinaison doprateurs et de valeurs.
Les fonctions de recherche de motifs du PHP retournent vrai si le motif a t
trouv dans une chane de caractres, elles permettent aussi dextraire de
cette chane la sous chane qui correspond au motif et de la modifier.
Une utilisation rcurrente des regex consiste en la recherche de mots cls
dans des fichiers ou dans une base de donnes ou encore en la vrification
des donnes saisies par lutilisateur afin de sassurer quelles respectent un
format prdfini, ou mme doprer des conversions de format.
4 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Exemple
Par exemple on peut se lancer la recherche du mot voiture dans la chane
$str :
if(ereg(voiture, $str)) {
echo ok;
} else {
echo invalide;
}
Le motif ici est rduit sa plus simple expression : voiture est le motif de
recherche, il consiste juste en une valeur (chane de caractres).
On peut le compliquer pour accepter une majuscule en dbut de mot :
[Vv]oiture. On pourra galement interdire que ce motif soit inclus dans un
mot plus grand comme voiturette : [Vv]oiture([^[:alpha:]]|$). Mais
autoriser son pluriel : [Vv]oiture(s)?([^[:alpha:]]|$).
Vous voyez, a devient vite du charabia !
5 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Les fonctions PHP
ereg($motif, $chane [, $vars]) : retourne VRAI si le motif $motif est trouv
dans la chane $chane. Le tableau $vars contiendra les sous chanes de
$chane vrifiant le motif.
ereg_replace($motif, $nouvelle, $chane) : retourne la chane $chane dont
les sous chanes vrifiant le motif $motif sont remplaces par la chane
$nouvelle.
split($motif, $chane [, $num]) : retourne un tableau dau maximum $num
lments des sous chanes de $chane qui se trouvent spares par des
dlimiteurs vrifiant le motif $motif.
Les fonctions eregi(), eregi_replace(), spliti() sont identiques aux
prcdentes mais insensibles la casse.
Note : la casse est la diffrence majuscules/minuscules.
6 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Description des motifs
Les motifs sont dcrits par ces trois caractristiques :
les caractres, chanes ou classes de caractres qui les composent
leur nombre dapparition
leur position
les alternatives
7 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Chane de caractres
Un motif peut tre constitu dune simple chane.
Exemple : ereg(Paris, Je vis Paris.)
Cet exemple renvoie VRAI car le motif Paris a t trouv dans la chane Je
vis Paris..
Exemple : ereg(hugo, Hugo Pratt fut un grand dessinateur de BD.)
Cet exemple renvoie FAUX car le motif hugo na pas t trouv dans la
chane Hugo Pratt fut un grand dessinateur de BD..
Attention la casse des caractres !
8 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Alternative
Un peut dcider dimposer la prsence dune chane parmi plusieurs grce au
caractre spcial de signification OU boolen : | .
Exemple : ereg(hugo|Hugo|HUGO, Hugo Pratt fut un grand dessinateur
de BD.)
Cet exemple renvoie VRAI car le motif a t trouv dans la chane Hugo Pratt
fut un grand dessinateur de BD.. Et cest en particulier Hugo qui a t
trouv.
Exemple :
$motif = hugo|Hugo|HUGO;
$str = Hugo Pratt fut un grand dessinateur de BD.;
if(ereg($motif, $str, $regs))
foreach($regs as $elem)
echo $elem.<br />;
Cet exemple recherche et affiche le motif trouv. Ici ce sera Hugo.
9 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Ensemble de caractres (I)
On peut vouloir recherche une chane complte : voiture ou bien seulement
un caractre parmi un ensemble. Les ensembles sont dfinis entre crochets [ ].
Pour rechercher lune des voyelles dans un mot, on utilisera le motif suivant :
[aeiouy].
Exemple : ereg([aeiouy], voiture)
Cet exemple renvoie VRAI puisque le mot voiture contient au moins une des
voyelles dfinies dans le motif.
Pour rechercher une plage de caractres, on indiquera le premier et le dernier
caractres spars par un tiret pour demander de rechercher un caractre
parmi ceux de lalphabet situs entre ces deux caractres. Pour rechercher les
caractres entre a et d dans le mot voiture :
Exemple : ereg([a-d], voiture)
Cet exemple renvoie FAUX car le mot voiture ne contient aucune des lettres
de lalphabet comprises entre a et b.
10 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Ensemble de caractres (II)
On peut tendre notre logique aux chiffres. Pour rechercher un chiffre entre 0
et 9, le motif sera le suivant : [0-9].
Exemple : ereg([0-9], voiture)
Cet exemple renvoie FAUX car la chane voiture ne contient aucun des
chiffres parmi ceux de lensemble du motif.
On peut ajouter notre ensemble loprateur de ngation ^. Cet oprateur ne
peut apparatre quen dbut densemble et sapplique tout lensemble.
Exemple : ereg([^0-9], voiture)
Cet exemple renvoie VRAI car effectivement, la chane voiture ne contient
aucun des chiffres parmi ceux de lensemble du motif.
Autre exemple : ereg([^aeiouy], voiture)
Cet exemple renvoie FAUX puisque le mot voiture contient au moins une des
voyelles dfinies dans le motif.
11 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Ensemble de caractres (III)
Il est possible de combiner ensembles et plages de caractres.
Exemple : ereg([a-zA-Z], voiture)
Cet exemple renvoie VRAI car la chane voiture contient au moins un des
caractres dfinis par le motif. Le motif dfini tous les caractres minuscules
entre a et z ainsi que tous les caractres majuscules entre A et Z.
Exemple : ereg([^a-zA-Z], voiture)
Ici on se demande si notre chane vrifie le motif suivant : ne pas trouver de
lettres quelles soient minuscules ou majuscules. Cet exemple renvoie FAUX
puisque voiture contient des lments du motif : des caractres minuscules.
12 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Classes de caractres (I)
Il existe des ensembles prdfinis de caractres, chacun portant un nom
particulier. Ainsi, lensemble des chiffres : [0-9] sappelle [[:digit:]].
Les exemples suivants sont quivalents :
ereg(0|1|2|3|4|5|6|7|8|9, $chaine)
ereg([0-9], $chaine)
ereg([[:digit:]], $chaine)
Les exemples suivants sont quivalents :
ereg([^[:alnum:]], $chaine)
ereg([^[:alpha:][:digit:]], $chaine)
ereg([^A-Za-z0-9], $chaine)
Les exemples suivants sont quivalents :
ereg([[:alpha:]], $chaine)
ereg([[:upper:][:lower:]], $chaine)
ereg([A-Za-z], $chaine)
13 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Classes de caractres (II)
Caractres imprimables, excepts ceux de contrle [ -~] [[:print:]]
Caractres dchappement [\x00-\x19\x7F] [[:cntrl:]]
Tout type despace [ \t\v\f] [[:space:]]
Caractres de ponctuation [!-/:-@[-{-~] [[:punct:]]
Caractres en majuscule [A-Z] [[:upper:]]
Caractres en minuscule [a-z] [[:lower:]]
Caractres affichables et imprimables [!-~] [[:graph:]]
Caractres hexadcimaux [0-9a-fA-F] [[:xdigit:]]
Espaces ou tabulations [\x09] [[:blank:]]
Caractres numriques [0-9] [[:digit:]]
Caractres alphabtiques [A-Za-z] [[:alpha:]]
Caractres alphanumriques [A-Za-z0-9] [[:alnum:]]
Description Equivalent Squence
14 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Caractres spciaux
Les caractres spciaux sont ceux qui possdent une signification particulire
aux yeux des rgles de construction des motifs des regex. Ces caractres ne
peuvent pas tre utiliss comme nimporte quel autre, sauf les prcder dun
antislash \.
Ils sont les suivants : ^ . [ ] $ ( ) | * + ? { } \
Toutefois ces caractres (sauf ] et -) perdent leur caractre spcial lorsquils
sont utiliss entre crochets. Comme en C, pour despcialiser un caractre, il
faut le faire prcder dun antislash \. A noter quen dehors des crochets, le
tiret - na pas signification particulire. Pour utiliser malgr tout les caractres ]
et - entre crochets, il faudra ruser, et les placer respectivement en dbut et en
fin densemble.
Exemple : ereg([][(){}], $chaine)
tudions le comportement de PHP face ce motif : il rencontre un premier
crochet ouvrant quil considre comme spcial et prcdant la dfinition dun
ensemble de caractres. Puis vient le crochet fermant, comme lensemble vide
nest pas connu par les regex PHP, il considre ce crochet comme nimporte
lequel des caractres normaux. Ensuite vient le crochet ouvrant, comme le
mode ensemble est dj actif, il ne vas en ouvrir un autre et considre ce
crochet comme un caractre normal. Et vient enfin le dernier caractre le
crochet fermant qui clt le mode ensemble.
15 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Cardinalit
Un caractre ou un ensemble de caractres peut tre interdit, facultatif,
obligatoire ou rpt un certain nombre de fois selon la syntaxe qui
laccompagne.
Obligatoire : apparat une ou plusieurs fois +
Doit apparatre exactement n fois {n}
Doit apparatre au moins n fois {n,}
Doit apparatre entre n et m fois avec n<m {n,m}
Facultatif : apparat zro, une ou plusieurs fois *
Facultatif : apparat une ou zro fois ?
description syntaxe
Exemple : ereg([[:lower:]]?[[:digit:]]{4}, la voiture K2000 est intelligente)
Retourne VRAI car la sous chane K2000 contient un caractre minuscule
optionnel ([[:lower:]]?) suivi de quatre chiffres obligatoires ([[:digit:]]{4}).
16 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Caractre
Pour chercher un caractre nimporte lequel (y compris les caractres de
fonction) : . (point).
Exemple : ereg(http://.+\.com, http://cyberzoide.developpez.com)
Cet exemple retourne VRAI car http://cyberzoide.developpez.com
commence par http:// suivi de nimporte quel caractre . prsent une ou
plusieurs fois et finissant par .com (dont le point est despcialis).
17 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Position
On peut insrer dans le motif des contraintes de positions dans la chane :
dbut et fin.
Fin de chane $
Dbut de chane ^
description syntaxe
Exemple : ereg(^[[:upper:]].+\.$, Les Misrables.)
Retourne VRAI car Les Misrables. commence par une majuscule et fini par
un point (avec entre les deux un nombre indfini de caractres).
Exemple : ereg(^\$, $5.000)
Retourne VRAI car $5.000 commence par le symbole de lunit montaire
amricaine, le dollars. Le caractre de position de fin de chane a t
despcialis par un antislash.
18 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Exercice format montaire
Ex. 1 : Construire un motif permettant de vrifier la validit dune chane
comportant un prix en Euros. Le prix pourra comporter de 0 2 dcimales. La
virgule sera le sparateur de dcimales. Les milliers (groupes de 3 chiffres)
seront spars par un point. Le prix se terminera par EUR . La chane ne
devra rien comporter dautre.
Solution : ereg(^[0-9]{1,3}(\.[0-9]{3})*(,[0-9]{0,2})? EUR$, $str)
^xxx EUR$ : la chane contient seulement le nombre xxx suivi dun espace et de lunit
EUR .
(,[0-9]{0,2})? : le nombre contient optionnellement des dcimales introduites par une
virgule, le nombre de dcimales varie de 0 2
(\.[0-9]{3})* : il y a 0 ou plusieurs groupes de milliers spars par un point
[0-9]{1,3} : il y a 1 ou 3 chiffres au minimum dans notre nombre
5.000,00 EUR
100,555 EUR 5.299.138,25 EUR
30.5 EUR 1.500 EUR
1 500 EUR 20,5 EUR
25, EUR 0 EUR
mauvais bon
19 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Remplacement
Les expressions ne se limitent pas la recherche de motifs mais permettent
aussi de remplacer les sous-chanes satisfaisant un motif par une autre chane
via la fonction ereg_replace().
Exemple 1 :
$str = Je roule en voiture.;
$str = ereg_replace(voiture, automobile, $str);
echo $str ; // affiche : Je roule en automobile.
Exemple 2 :
$str = cyberzoide@yahoo.fr;
$str = ereg_replace(@(.+)\.fr, @wanadoo.fr, $str);
echo $str ; // affiche : cyberzoide@wanadoo.fr
20 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Fractionnement
Il est possible de fractionner une chane en plusieurs sous-chanes spares
par un dlimiteurs satisfaisant un motif, en utilisant la fonction split().
Exemple 1 :
$str = Hugo:Etivant:cyberzoide@yahoo.fr;
$tab = split(:, $str, 3);
foreach($tab as $elem) {
echo $elem, <br />;
}
Cet exemple spare les 3 premires sous-chanes dlimites par le caractre
deux points comme cela se fait pour lanalyse dune ligne du fichier .passwd.
Exemple 2 :
$str = 23-03-2003;
list($jour, $moi, $an) = split([./-], $str);
Cet exemple spare les sous-chanes dune date dont le sparateur peut tre
lun de la plage suivante : point, slash et tiret.
// affiche :
Hugo
Etivant
cyberzoide@yahoo.fr
21 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Parenthses capturantes (I)
Syntaxe :
ereg($motif, $chaine, $regs);
Les sous-chanes de $chaine correspondantes au $motif de recherche sont
enregistres dans le tableau $regs si ce dernier argument optionnel de ereg()
est spcifi. $regs[0] contient une copie de la chane dorigine $chaine.
$regs[1] contiendra la premire parenthse capturante (celle qui commence le
plus tt), $regs[2] contiendra la deuxime parenthse capturante (celle qui
commence aprs la premire), et ainsi de suite.
Exemple :
$email = "cyberzoide@yahoo.fr";
ereg("^(.+)@(.+)\.(.+)$", $email, $regs);
echo $regs[1], ':', $regs[2], ':', $regs[3]; // affiche cyberzoide:yahoo:fr
Cet exemple extrait dune adresse email le compte, le domaine et le suffixe
gographique/catgoriel.
22 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Parenthses capturantes (II)
Un autre atout des regex est de pouvoir capturer la sous-chane satisfaisant le
motif afin de linclure dans une chane de remplacement. Pour cela, on va
employer les parenthses afin dencadrer la sous-chane du motif quil
conviendra de capturer (que lon appellera instance ). Puis, on fera
rfrence cette instance du motif via la syntaxe suivante : \\X o X est le
numro de la parenthse que lon souhaite capturer. Car il est possible de
capturer 9 instances. Linstance \\0 faisant rfrence la chane en entier et \\1
la premire parenthse capturante.
Exemple :
$date = "21-02-2003";
$date = ereg_replace("([[:digit:]]{2})-([[:digit:]]{2})-([[:digit:]]{4})",
"\\2/\\1/\\3", $date); // affiche 02/21/2003
Cet exemple convertit une date MySQL au format francophone.
Le mme rsultat aurait pu tre obtenu par lutilisation successive des
fonctions : split(), list() et ereg_replace(). Mais grce aux parenthses
capturantes, on a tout fait en une seule commande !
23 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Autres fonctions de traitement de chanes
Les expressions rgulires sont un outil puissant pour traiter des chanes de
caractres dont on connat le schma, cest--dire la manire gnrale dont
elles sont grammaticalement composes.
Malgr leurs qualits, elles souffrent dun dfaut majeur : la lenteur dexcution
du moteur de traitement de ces chanes.
Ainsi, il est recommand dutiliser le plus souvent possible les fonctions
standard de traitement des chanes de caractres afin dacclrer le temps de
traitement de vos scripts.
On peut organiser ces fonctions en 3 classes :
- recherche, comparaison (similar_text, strcmp, strnatcmp, strcasecmp,
strncmp, substr, strstr, strspn, strpos)
- remplacement (AddSlashes, AddCSlashes, htmlentities, htmlspecialchars,
QuoteMeta, trim, nl2br, strip_tags, StripSlashes, str_pad, str_repeat,
str_replace, strtr, ucfirst, ucword, wordwrap)
- fractionnement (explode, implode, join, chunk_split, strtok)
24 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Tableau comparatif
Certaines fonctions standard sont quivalentes une expression rgulire, il
faudra alors privilgier ces premires :
ereg_replace(a, @, $str) strtr($str, a, @)
split($op, $str) strtok($str, $op)
ereg_replace(\[^\], , $str) stripslashes($str)
ereg_replace(<.+>, , $str) strip_tags($str)
ereg(^$str1$, $str2); strcmp($str1, $str2)
ereg_replace(^( )+,, $str) ltrim($str)
ereg_replace(\n, <br />,$str) nl2br($str)
Fonction regex Fonction standard
25 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Les fonctions standard (I)
strcmp($str1, $str2) : compare en binaire les 2 chanes, retourne un entier
ngatif si $str1<$str2, positif si $str1>$str2, nul si $str1=$str2.
strncmp($str1, $str2, $i) : comme strcmp() mais sur les $i premiers
caractres.
strcasecmp($str1, $str2) : comme strcmp() mais insensible la case.
strncasecmp($str1, $str2) : comme strncmp() mais insensible la case.
strnatcmp($str1, $str2) : comme strcmp() mais dans lordre naturel (0-
9,a-z,A-Z).
strnatcasecmp($str1, $str2) : comme strcasecmp() mais dans lordre
naturel .
strstr($str1, $str2) : retourne le contenu de $str1 depuis la premire
occurrence de $str2 jusqu la fin.
stristr($str1, $str2) : comme strstr() mais insensible la casse.
strrchr($str1, $str2) : comme strstr() mais partir de la dernire occurrence.
substr($str, $i [, $n]) : retourne la sous-chane de $str dbutant la position
$i jusqu $n.
26 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Les fonctions standard (II)
addslashes($str) : retourne la chane $str dont les caractres , et \ sont
protgs par un antislash.
stripslashes($str) : fonction rciproque de addslashes.
quotemeta($str) : ajoute un antislash devant les caractres suivants : . \\ + * ?
[ ^ ] ( $ ).
htmlspecialchars($str) : convertit tous les caractres spciaux en leur code
HTML, par exemple < devient &lt; Synonyme : htmlentities().
ltrim($str) : supprime les espaces de dbut de chane
rtrim($str) : supprime les espaces de fin de chane, synonyme : chop()
trim($str) : ltrim() + rtrim()
explode($op, $str [, $n]) : scinde la chane $str en au plus $n morceaux en
utilisant le sparateur $op. Retourne un tableau.
implode($op, $tab) : fonction rciproque de explode().
strtok([$str,] $op) : morcelle la chane $str via le sparateur $op.
chunk_split($str1 [, $n [, $str2]]) : morcelle $str1 par insertion de $str2 tous
les $n caractres.
27 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Les fonctions standard (III)
ord($str) : retourne la valeur ASCII du caractre
chr($str) : fonction rciproque de ord()
strlen($str) : retourne la taille de $str (i.e. le nombre de caractres)
str_pad($str1, $n [, $str2 [, $type]]) : complte la chane $str1 avec $n fois
$str2 (ou $n espaces par dfaut) en fin de chane par dfaut ou en dbut
($type = STR_PAD_LEFT) ou encore sur les deux cts (STR_PAD_BOTH).
str_repeat($str, $n) : rpte $n fois la chane $str.
strrev($str) : inverse une chane
strpos($str1, $str2 [, $n]) : recherche la premire occurrence de $str2 dans la
chane $str1 partir de la position $n (au dbut par dfaut).
strrpos($str1, $str2) : comme strpos() mais un caractre partir de la fin
substr_count($str1, $str2) : compte le nombre doccurrences de $str2 dans
$str1
28 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Les fonctions standard (IV)
substr_replace($str1, $str2, $i [, $n]) : remplace $n caractres depuis $i
dans $str1 par $str2
strtolower($str) : conversion en minuscules
strtoupper($str) : conversion en majuscules
ucfirst($str) : conversion en majuscule du premier caractre de la chane
ucwords($str) : conversion en majuscule du premier caractre de chaque mot
wordwrap($str [, $n [, $op [, $test]]]) : ajoute la csure $op dans $str tous
les $n caractres. Si $test vaut 1, les mots trop long seront coups. Par dfaut
dcoupe tous les 75 caractres par \n.
nl2br($str) : remplace les sauts de ligne \n par la balise XHTML <br />.
29 http://cyberzoide.developpez.com Le CyberZode Qui Frtille
Historique
15 avril 2004 : corrections mineures
3 mars 2003 : quelques ajouts, plus dexemples (29 diapos)
23 fvrier 2003 : parenthses capturantes, fonctions standard (28 diapos)
23 dcembre 2002 : cration du document (19 diapos)
Agissez sur la qualit de ce document en envoyant vos critiques et
suggestions lauteur.
Pour toute question technique, se reporter au forum PHP de Developpez.com
Hugo Etivant
cyberzoide@yahoo.fr
http://cyberzoide.developpez.com/

Vous aimerez peut-être aussi