Une expression régulière est une structure logique connue aussi sous le nom de "model" ou "pattern" qui permet de décrire la forme que doit vérifier une chaîne de caractères. Pour mieux comprendre le principe je vais reprendre le même exemple que nous avons vu en Javascript.
Imaginez qu'on invite un client à saisir une adresse mail dans un champ de saisie. Afin de s'assurer si ce qu'il a entré respecte la forme conventionnelle d'un email, on peut vérifier les points suivants:
L'arobas figure-t-il dans l'adresse mail?
Y a-t-il un point avant le TLD?
Est ce qu'il y a un caractère ou plus avant l'arobas?
Le nom de domaine semble-t-il valide?
Est ce que l'email ne contient pas de caractères non autorisés comme les espaces?
...
Afin de vérifier tous ces points, on peut faire appel aux fonctions qu'on a déjà vu pour les chaînes de caractères. En les combinant, on pourrait bien se rapprocher de l'objectif. Cependant, le code sera volumineux et, dans la plupart des cas, ne sera pas en mesure de satisfaire à 100% tous les points décrits.
La solution magique consiste donc à faire appel aux expressions régulières.
POSIX et PCRE
En PHP, il existe deux familles d’expressions régulières. Elle font toutes la même chose: chercher des motifs au sein d'une chaîne de caractères. Bien qu'il partagent des fois les mêmes caractères spéciaux au sein des models, il existe quand même de nettes différences entre les deux. Ces deux familles sont:
POSIX: il s'agit d'une famille d'expressions régulières utilisée en PHP. POSIX est l'acronyme de Portable Operating System Interface.
PCRE: signifie Perl Compatible Regular Expressions. C'est une famille d'expression régulières qui vient du langage PERL.
La principale différence entre les deux familles c'est le temps d’exécution. En effet, les PCRE sont plus rapides que les POSIX, surtout quand il s'agit d'expressions régulières longues et complexes. Une autre différence se manifeste dans la syntaxe. Bien que la plupart des caractères spéciaux des expressions peuvent être utilisés pour les deux familles. Il en existe qui sont propres à chaque famille.
Expressions régulières POSIX
Les fonctions
Les fonctions qui traitent les expressions régulières de la famille POSIX les plus courantes sont: ereg(), mb_ereg(), ereg_replace(), mb_ereg_replace(), split() et mb_split().
Fonctions ereg() et eregi():
La fonction ereg($motif,$chaine) permet de vérifier l'existence du motif $motif dans la chaîne de caractères $chaine. La variable $motif représente l'expression régulière ou le model à vérifier. La fonction ereg() retourne true si le motif existe dans la chaîne ou false si le motif n'est pas trouvé.
Exemple:
<?php
$str="Bonjour";
if(ereg("^B",$str))
echo "La chaîne commence par B";
else
echo "La chaîne ne commence pas par B";
?>
On obtient le résultat:
La chaîne commence par B
En effet, le motif dit bien que la lettre B doit figurer au début de la chaîne (symbole ^).
La fonction eregi() fait le même traitement que ereg() mais ne vérifie pas la casse (elle ne différencie pas entre minuscules et majuscules au sein des motifs).
Notez que les fonctions ereg() et eregi() sont obsolètes.
Fonctions mb_ereg() et mb_eregi():
La fonction mb_eregi($motif,$chaine) fait le même traitement que la fonction ereg(). Cependant, elle permet de supporter les expressions régulières qui font appel à des caractères multi-octes (multi byte).
La fonction mb_eregi() ne vérifie pas la casse.
Fonctions ereg_replace() et eregi_replace():
La fonction ereg_replace($motif,$remp,$chaine) permet de chercher l'expression $motif dans la chaîne de caractères $chaine et le remplacer par $remp.
En fait, le motif "jour" est remplacé par "soir" dans le chaîne "Bonjour". Le dollars ($) après "jour" signifie que le motif doit figurer à la fin de la chaîne.
Notez que les fonctions mb_ereg() et mb_eregi() sont obsolètes.
La fonction eregi_replace() fait le même traitement que ereg_replac() mais ne vérifie pas la casse.
Fonctions mb_ereg_replace() et mb_eregi_replace():
La fonction mb_ereg_replace($motif,$remp,$chaine) fait le même traitement que la fonction ereg_replace() avec le support des caractères multi-octets.
La fonction mb_eregi_replace() ne vérifie pas la casse.
Fonctions split() et spliti():
La fonction split($motif,$chaine) permet de découper la chaîne de caractères au niveau des occurrences $motif. Les morceaux de la chaîne seront ensuite stockés dans un tableau. Son fonctionnement rappelle celui de la fonction explode(). Cependant, split() prend en charge les expressions régulières.
La chaîne est découpée au niveau des caractères "o". On aurait pu faire ce traitement à l'aide de la fonction explode() car nous n'avons pas réellement évoqué une expressions régulière proprement dite.
La fonction print_r(), dans ce cas, permet d'afficher le contenu d'un tableau avec les indexes associés.
La fonctin spliti() ne vérifie pas la casse.
Fonction mb_split():
La fonction mb_split($motif,$chaine) permet de faire le même traitement que la fonction split() avec un support des caractères multi-octets.
La fonction mb_spliti() n'existe pas.
Caractères spéciaux d'une expression régulière
Au sein d'une expression régulière, certains caractères sont considérés comme tels et d'autre sont des caractères spéciaux que la fonction évalue. Voici la liste des caractères spéciaux souvent utilisés:
caractères spécial
Signification
.
Un seul caractère quelconque
+
Le motif précédent doit figurer au moins une fois, le max n'est pas déterminé
*
Le motif précédent doit figurer au moins 0 fois, le max n'est pas déterminé
()
Pour grouper un ensemble de caractères en tant que motif unique
[]
Pour désigner un ensemble de motifs dont , au moins, l'un d'entre eux doit figurer
-
Désigne un intervalle s'il est déclaré entre les crochets. Exemple: [a-z] signifie l'alphabet minuscule
?
Le motif précédent doit figurer 0 ou une fois.
^
Le motif suivant doit figurer au début de la chaîne
$
Le motif précédent doit figurer à la fin de la chaîne
{}
Pour spécifier le minimum et le maximum de fois où l'occurrence doit figurer. Exemple: {1,3} désigne que l'occurrence figure entre 1 et 3 fois.
En fait, nous avons spécifié une expression simple pour estimer si l'email est valide ou non. Nous avons juste vérifié s'il y a au moins n'importe quel caractère avant l'arobas, le caractère arobas, au moins n'importe quel caractères entre l'arobas et le point, le caractère point (qu'on a déspécialisé avec l'antislash pour qu'il ne soit pas pris pour un caractère spécial), et en fin, au moins n'importe quel caractère après le point.
Séquences utiles pour simplifier les expressions régulières POSIX
Imaginez avec moi si on veut vérifier la présente d'un caractère alphabétique (minuscule ou majuscule) ou caractère numérique au sein d'une chaîne de caractères. Le model contiendra donc quelque chose qui ressemble à [a-zA-Z0-9]. Heureusement, il existe des séquences pratiques pour les expressions régulières de la famille POSIX. Par exemple, le model précédent peut s'écrire [[:alnum:]] .
Voici la liste des séquences les plus fréquentes:
Séquence
Signification
[[:alnum:]]
Tous les caractères alphabétiques ou numériques (équivalent à [a-zA-Z0-9])
[[:alpha:]]
Tous les caractères alphabétiques (équivalent à [a-zA-Z])
[[:digit:]]
Tous les caractères numériques (équivalent à [0-9])
[[:blank:]]
Tous les types d'espaces et tabulation
[[:xdigit:]]
Caractères hexadécimaux (équivalent à [a-fA-F0-9])
[[:graph:]]
Tous les caractères affichables et imprimables
[[:punct:]]
Tous les caractères de ponctuation
[[:cntrl:]]
Caractères d’échappement
Expressions régulières PCRE
Il s'agit de la famille des expressions régulières la plus recommandée vu sa rapidité surtout lorsqu'il s'agit de motifs complexes.
Les fonctions
Nous allons nous intéresser aux fonctions preg_match(), preg_replace() et preg_split().
Fonction preg_match():
La fonction preg_match($motif,$chaine) peut contenir plusieurs paramètres. Pour simplifier, nous allons nous contenter des deux premiers à savoir, $motif qui désigne l'expression régulière et $chaine qui représente la chaîne de caractères dans laquelle on vérifie la présence du motif.
Le motif d'une expression PCRE doit toujours être placé entre des délimiteurs de votre choix. Le plus courant c'est d'utiliser un slah ou un dièse.
Par exemple, si on veut vérifier la présence de l'arobas dans la chaîne $email, alors le code ressemblerait à ceci:
En effet, nous estimons qu'un email valide commence par un nom d'utilisateur (qui peut contenir des lettres, chiffres, tirets, sous-tirets ou points), suivi d'un arobas, suivi du nom de domaine (qui peut être constitué de lettres, chiffres, tirets ou points) suivi du point déspécialisé et, en fin, le TLD qui est sensé contenir de 2 à 6 lettres.
Vous avez donc remarqué que les caractères spéciaux utilisés sont les même que ceux du POSIX.
Fonction preg_replace:
La fonction preg_replace($motif,$remp,$chaine) permet de chercher le motif $motif dans la chaîne de caractères $chaine et le remplacer par $remp.
Nous avons cherché le motif ".tld" à la fin de la chaîne (il faut déspécialiser le point), qu'on a remplacé par ".com" (dans ce cas, le point ne dois pas être déspécialisé car le deuxième paramètre n'est pas une expression régulière).
Fonction preg_split:
La fonction preg_split($motif,$chaine) éclate la chaîne de caractères $chaine au niveau des occurrences décrits par $motif et dépose les fragments de la chaîne dans un tableau.
La chaîne a été éclatée au niveau des caractères o. On aurait pu avoir le même résultat avec la fonction explode(), sauf que celle ci ne supporte pas des motifs sous forme d'expressions régulières.
Séquences utiles pour simplifier les expressions régulières PCRE
Comme pour la famille POSIX, PCRE dispose d'un ensemble de séquences qui permettent de simplifier nettement l'écriture des expressions régulières.
Ce tableau donne un aperçu sur les séquences les plus courantes:
Séquence
Signification
d
Tous les chiffres (équivalent à [0-9])
D
Tout ce qui n'est pas un chiffre (équivalent à [^0-9])
w
Tous les caractères alphabétique, numériques ou caractère sous-tiret (équivalent à [a-zA-Z0-9_])
W
Tous les caractères qui ne sont pas alphabétiques, numériques ou caractère sous-tiret (équivalent à [^a-zA-Z0-9_])