Les expressions regulieres sont souvent utilisees en PHP quand on doit faire des traitements conditionnels tres pousses sur les chaines de caracteres. Ce chapitre est malheureusement complique a comprendre, et nous aborderons plein d'exemples simples qui je l'espere vous permettront de faire des choses plus compliquees ensuite.
Une expression reguliere (aussi appelee regex) va par exemple vous permettre de savoir si une chaine est composee de 6 caracteres numeriques, de savoir si elle commence par un "a" tout en finissant par un "w" ou encore de savoir si il s'agit d'une date valide, etc ...
Toutes ces conditions que l'on fixe se presentent sous la forme d'une chaine de caracteres qui peut etre immense en fonction de ce que l'on souhaite savoir ou recuperer.
En PHP, il existe deux "langages" pour les expressions regulieres. Ces deux langages sont le POSIX et le PCRE. Nous etudierons les fonctions utilisant le langage PCRE, plus performant que le POSIX (que ce soit en terme de puissance ou de rapidite de traitement). Les fonctions utilisant le PCRE commencent generalement par le prefixe "preg_".
Voici une liste des fonctions PCRE que nous serons amenees a utiliser (il en existe d'autres) :
Ces fonctions s'utilisent generalement de la maniere suivante (pour les fonctions de remplacement) :
preg_X('masque', 'chaine de remplacement', 'chaine de caracteres dans laquelle on appliquera le masque');
Les fonctions de comparaison sont plutot de ce style la :
preg_Y('masque', 'chaine de caracteres dans laquelle on appliquera le masque');
La chaine "masque" correspond a une expression reguliere. Nous allons voir plus bas comment creer des expressions regulieres. Avant toute chose, il faut savoir qu'une regex est toujours delimitee par deux caracteres identiques appeles delimiteurs. Ces delimiteurs sont importants car ils vont vous permettre d'ajouter des options a votre expression reguliere (comme par exemple l'insensibilite aux majuscules/minuscules).
Voici l'exemple general d'utilisation d'une regex :
`masque`options
Ce qui peut donner par exemple :
`[a-z]*`i
Ici, vous ne le savez pas encore mais ceci designe une chaine composee de lettres uniquement, majuscules ou minuscules (le i dans l'option signifie que la recherche est insensible aux minuscules ou majuscules)
La recherche d'une chaine de caracteres simple peut se faire avec la fonction strpos() de PHP, qui sera bien plus rapide qu'une expression reguliere. Toutefois, ses fonctionnalites sont tres limitees car elle ne peut disposer en parametre que d'une chaine fixe. Avec une expression reguliere vous allez pouvoir imposer des conditions performantes sur la recherche.
Pour rechercher une chaine suivant des conditions precises, on utilise la fonction preg_match(). Elle s'utilise comme ceci :
<?php
$chaine = 'Un exemple de chaine simple';
if(preg_match('`exemple`', $chaine))
{
echo 'Vrai, la chaine correspond au masque';
}
else
{
echo 'Faux, la chaine ne correspond pas au masque';
}
?>
Ici, la chaine correspond au masque car nous cherchons la chaine "exemple" qui se situe bien dans la phrase "Un exemple de chaine simple". Bon, vous vous imaginez que les fonctions de preg_match() ne se limitent pas a ca, sinon utiliser strpos() ...
Voyons d'autres cas de figure :
<?php
$chaine = 'Un exemple de chaine simple';
if(preg_match('`Exemple`', $chaine))
{
echo 'Vrai, la chaine correspond au masque';
}
else
{
echo 'Faux, la chaine ne correspond pas au masque';
}
?>
Ici, vous aurez un resultat faux car le E de exemple est en majuscule. Pour remedier a ce probleme, on utilise l'option "i" qui signifie que le masque ne tient pas compte des minuscules et majuscules. Les options se placent apres le deuxieme delimiteur (ici le caractere `) :
<?php
$chaine = 'Un exemple de chaine simple';
if(preg_match('`Exemple`i', $chaine))
{
echo 'Vrai, la chaine correspond au masque';
}
else
{
echo 'Faux, la chaine ne correspond pas au masque';
}
?>
Ici, preg_match() renvoie TRUE. Voyons d'autres cas :
| Chaine | Regex | Resultat |
| 'Un exemple de chaine simple' | `exemple` | Vrai (le mot "exemple" se trouve bien dans la chaine) |
| 'Un exemple de chaine simple' | `compliquee` | Faux (le mot "compliquee" ne se trouvant pas dans la chaine) |
| 'Un exemple de chaine simple' | `Exemple` | Faux car le E est en majuscule dans la regex et pas dans la chaine |
| 'Un exemple de chaine simple' | `Exemple`i | Vrai car le i rend insensible a la casse (majuscules/minuscules) la regex |
Le symbole "ou" est designe en PCRE par une seule barre verticale (contrairement au PHP qui lui en demande deux dans les conditions habituelles).
Mettons que nous recherchions dans une chaine le mot "site" ou le mot "web". La regex pourra s'ecrire comme ceci :
`site|web`
| Chaine | Regex | Resultat |
| 'Bienvenue sur mon site web' | `site|web` | Vrai (on a bien soit site soit web dans la chaine) |
| 'BIENVENUE SUR MON SITE WEB' | `site|web` | Faux (aucun des deux mots n'est en minuscules) |
| 'BIENVENUE SUR MON SITE WEB' | `site|web`i | Vrai, on a rendu l'expression reguliere insensible a la casse |
| 'Bienvenue sur mon site' | `site|web` | Vrai car le mot "site" figure dans la chaine a analyser |
| 'Bienvenue sur mon espace web' | `site|web` | Vrai car le mot "web" figure dans la chaine a analyser |
| 'Bienvenue sur mon espace' | `site|web` | Faux car ni le mot "site" ni le mot "web" ne figurent dans la chaine |
Bon, nous allons maintenant voir quelque chose d'un peu plus precis. Il s'agit du debut et de la fin d'une chaine. Par exemple nous allons pouvoir dire "est-ce que cette chaine commence par la lettre A majuscule et se termine par un b minuscule ?"
Les deux symboles utilises pour designer cela sont ceux-ci :
| Chaine | Regex | Resultat |
| 'Anthony' | `^A` | Vrai (la chaine commence bien par un A) |
| 'Anthony' | `y$` | Vrai (la chaine se termine par un y) |
| 'Debut de phrase' | `^Dt$` | Faux car la chaine est differente de "Dt" |
| 'Bienvenue sur mon espace web' | `^Bienvenue sur mon espace web$` | Vrai car la chaine est identique des deux cotes |
| 'Bienvenue sur mon espace web' | `^Bienvenue web$` | Faux car il y a des mots entre le mot "Bienvenue" et le mot "Web" |
Les quantificateurs sont tres utiles, grâce a eux vous allez pouvoir dire "je veux savoir si cette chaine commence par 7 fois la lettre A", ou encore "il me faut un A, trois o et deux z".
Il faut tout d'abord retenir trois symboles :
Ces symboles s'appliquent uniquement a la lettre (ou au mot si vous placez des parentheses) qui est situe(e) a gauche du symbole.
| Chaine | Regex | Resultat |
| 'Anthony' | `An?thony` | Vrai (Il y a bien 0 ou 1 "n" apres le A) |
| 'Annnnnnthony' | `An?thony` | Faux (il y a plus de 1 "n" apres le A) |
| 'Annnnnnthony' | `An+thony` | Vrai (il y a bien au moins 1 "n" apres le A) |
| 'Chat' | `Chats?$` | Vrai car le mot "chat" peut ici aussi etre au pluriel (0 ou 1 "s"), ensuite on marque la fin de la chaine |
| 'Chat' | `Chats*$` | Vrai car * signifie "0", "1" ou "plusieurs" ici il n'y a pas de s, la condition reste quand meme vraie. |
Il existe un autre moyen de quantifier, cette fois plus precisement, une chaine ou une lettre, ou encore une classe de caracteres (on verra ce que c'est juste apres). On utilise pour cela les accolades. Voici comment ca fonctionne :
| Chaine | Regex | Resultat |
| 'Anthony' | `An{0,1}thony` | Vrai (Il y a bien 0 ou 1 "n" apres le A) |
| 'Annnnnnthony' | `An{2}thony` | Faux (il n'y a pas deux "n" apres le A) |
| 'Annnnnnthony' | `An{2,}thony` | Vrai (il y a bien au moins 2 "n" apres le A) |
Les classes de caracteres vont vous permettre d'effectuer des recherches precises tout en limitant le nombre de caracteres de vos expressions regulieres. Les classes de caracteres sont toujours contenues entre des crochets simples ou doubles (nous verrons certaines classes de caracteres speciales apres).
Voici un exemple d'expression reguliere incluant une classe de caracteres : `[nv]ous`
le [nv] signifie "n" OU "v". Les mots "nous" et "vous" seront donc acceptes, il s'agit donc de l'equivalent de `(n|v)ous`
| Chaine | Regex | Resultat |
| 'Nous' | `[nv]ous`i | Vrai (le i rend la regex insensible a la casse) |
| 'Nous' | `[vs]$` | Vrai (la chaine se termine bien par un v ou un s) |
Voyons maintenant quelques classes un peu speciales, elles ont de special le fait que l'on utilise un tiret entre plusieurs valeurs, il s'agit donc d'intervalles de caracteres. Nous allons voir ici quelques exemples rapides, car je pense que vous allez vite comprendre l'interet de cette syntaxe :
`[a-z]` : indique une lettre minuscule allant de a a z
`[0-3]` : indique un chiffre allant de 0 a 3
`[a-z0-9]` : indique des lettres minuscules OU des chiffres allant de 0 a 9
| Chaine | Regex | Resultat |
| 'Anthony' | `[a-z]*` | Faux (le premier A est en majuscules) |
| 'Annnnnnthony' | `[a-z]*`i | Vrai (les caracteres sont tous des lettres minuscules ou majuscules) |
| 'Annnnnnthony1' | `[0-9]$` | Vrai (la chaine se termine bien par un chiffre allant de 0 a 9) |
Vous pouvez egalement interdire un ou une plage de caracteres, cette fois-ci on utilise le symbole ^ place juste apres le premier crochet ouvrant. Il ne signifie plus "debut de la chaine" mais une interdiction.
| Chaine | Regex | Resultat |
| 'ANTHONY' | `^[^a-z]*$` | Vrai (la chaine ne contient pas de minuscules) |
| 'Anthony' | `^[^a-z]*$` | Faux (la chaine contient des minuscules) |
Voici maintenant quelques classes encore speciales, puisqu'elles sont contenues entre des doubles crochets. Ce sont des classes predefinies qui vont vous simplifier la syntaxe de vos regex :
Les metacaracteres sont des caracteres speciaux effectuant des actions bien precises sur les chaines. Voici la liste de ces caracteres :
[ ] ! ( ) { } ^ $ ? . + * \ #
Le probleme qu'ils generent est lorsque vous souhaitez les utiliser dans vos recherches ou remplacements de caracteres. Il faut les faire preceder d'un antislash \. Voici un exemple :
| Chaine | Regex | Resultat |
| 'ca va?' | `ca va?$` | Faux (la chaine ne se termine pas par 0 ou 1 "a") |
| 'ca va?' | `ca va\?$` | Vrai (on a echappe correctement le caractere) |
Attention, cette regle ne s'applique pas a l'interieur des classes de caracteres. Ainsi, la classe [ab+?] signifie que vous pourrez avoir la lettre "a" ou "b" ou "+" ou "?".
Les classes abregees vont vous permettre de reduire encore la longueur de vos expressions regulieres au mepris de leur comprehension directe. On utilise pour cela un antislash suivi d'un caractere, qui a eux deux signifient une classe de caractere plus complexe. Quand on connait la signification des lettres par coeur, c'est assez facile de ne pas se tromper, mais sinon la confusion peut regner, voila pourquoi personnellement je prefere utiliser les classes de caracteres simples. Voici la liste des classes de caracteres abregees :