Les expressions régulières avec PHP

PHP nous offre une variété de fonctions pour le traitement des chaînes de caractères. Parmi elles, on trouve les fonctions telle que strpos() pour rechercher une chaîne de caractères bien définie. Cependant, elles se limitent à des usages simples et il arrive qu'elles ne suffisent pas pour les manipulations de chaînes de caractère que l'on souhaiterait faire.

Dans le cas où l'on veut par exemple trouver les chaines qui commencent par un C, qui contiennent deux ou trois fois le caractère "a" et se terminent par un point, il est plus simple de faire appel aux expressions régulières.

En effet, ces dernières permettent de définir des critères de recherches beaucoup plus complexes. Elles offrent plusieurs possibilités notamment concernant la notion de répétion, la gestion des casses, gestion des nombre d'occurrence, etc. En général, dans une expression régulière on définit un motif pour valider la chaine lors d'une recherche.

Règles de base d'une expression régulière

Avant d'entamer le vif du sujet, notons que dans une expression régulière, une chaine de recherche est entourée de délimiteurs. Ces derniers peuvent être n'importe quel caractère non alphanumérique (ni lettre ni chiffre) sauf l'antislash "\". D'habitude, on utilise le slash "/" comme délimiteurs, mais une paire d'accolades, de crochets ou de parenthèses est aussi autorisée.

Quand à l'antislash "\" , il est utilisé pour échapper les caractères spéciaux. En effet, certain caractères peuvent avoir une signification particulière dans une expression régulière. Parfois certains caractères sont aussi utilisés comme critères de recherche. Dans ce cas, afin d'éviter toute ambigüité, nous allons devoir la protéger en utilisant le caractère d'échappement.

Notons aussi que les règles habituelles des chaînes de caractères s'appliquent également aux expressions régulières. Ainsi, dans une expression régulière, la chaîne \n fait partie des caractères spéciaux. Si elle fait partie des critères de recherche, il est nécessaire de la faire précéder d'un antislash.

Chaîne de recherche simple avec preg_match

La fonction preg_match() est le plus souvent utilisée en cas de recherche de caractère.

Elle peut prendre en premier argument une expression régulière et en second une chaîne de caractères référence. Si la chaîne de référence est valide par rapport à l'expression régulière, alors la fonction renvoie la valeur TRUE, si non elle renvoie FALSE.

Quand au troisième argument (ici : $out) qui est un tableau, il est d'une utilité particulière que l'on verra plus tard.

<?php
$texte = 'La fille est sage';
if(preg_match_all('/fille/', $texte,$out))
{
echo "Le texte contient la chaine fille";
}
else
{
echo "Le texte ne contient pas la chaine fille";
}
?>

La fonction preg_match() est utilisée de manière assez simple dans cet exemple. A la place de la fonction strpos(), elle va vérifier la présence de la chaîne "fille" dans le texte "La fille est sage".

Ceci dit, on trouvera mieux son intérêt dans une utilisation plus complexe, c'est-à-dire en construisant des expressions.

Construction d'expressions régulières

Pour construire une vraie expression régulière, plusieurs notions nécessitent d'être abordées.

Choix entre plusieurs chaines de caractère : preg_match_all

Les expressions régulières permettent de définir des critères de façon très souple. Dans l'exemple ci-dessus, on n'a recherché que le mot fille, mais supposons que l'on désire vérifier si la chaîne contient soit "une" soit "la". Voire même si la chaîne contient la fille ou une fille.

Pour cela, la barre verticale (pipe, caractère |) nous servira de délimiteur entre deux alternatives. Autrement dit, le caractère | se comporte comme un opérateur OU dans les expressions régulières.

Dans le code suivant, l'expression une|la trouve les chaînes contenant au moins une des deux chaines.

<?php
$texte = 'La fille est sage';
if(preg_match_all('/La|Une/', $texte,$out))
{
echo "Le texte contient l'une des chaines : La ou Une";
}
else
{
echo "Le texte ne contient aucune des chaines : La ou Une";
}
?>

Et si l'on rajoute le mot fille après, on peut trouver les chaîne qui contient "une fille" ou "la fille".

<?php

$texte = 'Une fille est sage';
if(preg_match_all('/(La|Une) fille/', $texte,$out))
{
echo "Le texte contient l'une des chaines : La fille ou Une fille";
}
else
{
echo "Le texte ne contient aucune des chaines : La fille ou Une fille";
}
?>

Liste de caractères autorisés ou interdits

Si vous devez introduire plusieurs alternatives dans votre critère de recherche, il est possible d'utiliser une syntaxe réduite à la place de plusieurs opérateur "|". Il s'agit de lister tous les caractères autorisés entre des crochets.

Par exemple [0123456789] permet de valider n'importe quel chiffre. Dans l'exemple suivant, on vérifie la présence de l'âge dans le texte.

<?php
$texte = "La fille de 8 ans est sage";
$recherche = '/[0123456789] ans/';
echo preg_match_all($recherche, $texte,$out);
?>

Pour lister des caractères interdits, on raisonne pareil, sauf que l'on doit ajouter un accent circonflexe avant la chaine de caractères. Cependant, certains confondent la définition d'une classe de caractères par négation à l'exclusion des caractères.

L'expression /[^b]/ peut valider une chaîne qui contient la lette b. Cela signifie que l'on cherche un caractère autre que b, c'est-à-dire valider les chaînes contenant des caractères autres que b. Il ne s'agit donc pas d'une exclusion des caractères concernés.

Classes de caractères prédéfinis

Il peut également être utile de vérifier si une chaîne contient des caractères d'un certain type (numérique, alphanumérique, ...) sans avoir à les énumérer. Il existe déjà des alternatives prédéfinis qui permettent de vérifier si une chaîne contient des caractères d’un certain type.

Ces classes de caractères sont entourées par un crochet et un deux- points dont voici la syntaxe : [:classe:]

Vous verrez dans le tableau suivant une récapitulation de certaines de ces classes :

Memo pour vos expressions régulières
Nom de la classeDescription
[:alnum:] caractères alphanumériques (équivalent à [A-Za-z0-9])
[:alpha:] caractères alphabétiques ([A-Za-z])
[:blank:] caractères blanc (espace, tabulation)
[:ctrl:] caractères de contrôle
[:digit:] chiffre ([0-9])
[:graph:] caractère d'imprimerie (qui fait une marque sur l'écran en quelque sorte)
[:print:] caractère imprimable (qui passe à l'imprimante ... tout sauf les caractères de contrôle)
[:punct:] caractère de ponctuation
[:space:] caractère d'espacement
[:upper:] caractère majuscule
[:xdigit:] caractère hexadécimal

Exemple d'utilisation des classes de caractère dans une expression régulière :

"[:punct:]|[:space:]" vérifier si une chaîne contient un caractère de ponctuation ou un caractère d'espacement

Début et fin d'une chaine

Pour désigner le début et la fin d'une chaine, on utilise respectivement les symboles ^ et $.

Ainsi :

  • "^start": désigne une chaîne qui commence par le mot "start">
  • "end$": désigne une chaîne qui se termine par le mot "end"
  • "^ok$": désigne une chaîne qui commence et se termine à la fois par le mot "ok"

Gestion des occurrences

Dans une expression régulière, les symboles + , ? et * permettent de définir un nombre d'occurrence d'un caractère.

  • un ou plusieurs : "+"
  • "abcd+": valide une chaîne qui contient "abc" suivie de un ou plusieurs "d" ("abcd", "abcdd" ...)
  • zéro ou un : "?"
  • "abcd?": valide une chaîne qui contient "abc" suivie de zero ou un "d" ("abc" ou "abcd")
  • zéro ou plusieurs : "*"
  • "abcd*": valide une chaîne qui contient "abc" suivie de zero ou plusieurs "d" ("abc", "abc" ...)
  • Il est également possible de faire pareil sur plusieurs caractères en groupant une suite de caractères dans des parenthèses.
  • "a(bc)*": chaîne qui contient "a" suivie de zero "bc" ou plus

Nombre d'occurrences fixes

On peut aussi fixer de vrais nombres en utilisant les chiffres correspondants avec des accolades.

Ainsi, abcd{3} correspond à 3 fois de répétition de la dernière lettre (ici : "d"). Ce qui est équivalent à abcddd.

Intervalle de nombre d'occurrence

Toujours avec des chiffres et des accolades, il est aussi possible de définir des intervalles. On veut par exemple chercher une chaîne répétée entre 3 et 6 fois. Pour cela, on sépare les deux bout par une virgule : abcd{3,5+ valide abcddd, abcdddd, abcddddd, abcdddddd

Notons que si nous omettons le minimum il sera considérée comme nul et si nous omettons le maximum, il sera considéré comme infini.

Recevez par email nos prochains conseils

Oseox sur Facebook Notifications via Facebook Oseox sur Twitter Notre actu sur twitter

Une question ? Venez la poser sur notre forum développement web !

A propos de l'auteur

Nicolas Galle

Nicolas Galle est développeur web sénior pour l'agence Aseox.