PHP : Initiation et aide-mémoire pour les expressions régulières (Regex)

Partager cet article

Temps estimé pour la lecture de cet article : 29 min

Il existe deux types d’expressions régulières, les regex POSIX (Portable Operating System Interface) ou les regex PCRE (Perl Compatible Regular Expressions). POSIX est un langage d’expressions régulières mis en avant par PHP, toutefois il présente un gros défaut, il est plus lent que PCRE. Ce dernier est issu du langage Perl, plus complexe, il est toutefois plus rapide et performant. C’est donc ce dernier qui va m’intéresser dans cet article.

Les bases

Regex Explications Exemple
^ Début de la chaîne /^G/ : la chaîne commence par un G
$ Fin de la chaîne /g$/ : la chaîne finie par un g
[] Un ensemble de possibilités /Lé[ao]/ : Léa ou Léo
[^] L’accent circonflexe permet d’interdire des caractères /^[^a-e]/ : la chaîne ne commence pas par une lettre comprise entre a et e
[a-z], [A-Z] ou \w Représente une lettre minuscule ou majuscule /[A-B][c-e]/ peut donner les chaînes suivantes : Ac, Ad, Ae, Bc, Bd et Be
[0-9] ou \d Représente un chiffre /[0-9]+/ on obtient au moins un chiffre entre 0 et 9
\s, \t, \r, \n et \f Un espace, une tabulation, un retour chariot, une fin de ligne et une fin de page /Regex\s<3/ : Regex <3
. Le point représente n’importe quel caractère excepter les sauts de lignes /Luci.n/ : Lucian, Lucibn, Luci5n…
Remarque : pour avoir juste le point en tant que caractère il suffit de l’échapper avec un slash : /\./
\D, \W Mettre une classe en majuscule désigne son inverse. \D = [^\d]

Les quantificateurs

Les quantificateurs permettent de spécifier le nombre d’apparition d’un caractère, groupe ou classe de caractères devant être présents pour qu’une correspondance soit trouvée.

Quantificateur Explications Exemple
? 0 ou 1 occurrence du pattern /http[s]?/ : donne http ou https
* 0 ou n occurrence du pattern /[a-z]*/ : 0 ou plusieurs lettres
+ 1 ou n occurrence du pattern /[0-9]+/ : 1 ou plusieurs chiffres
{} Désigne un nombre de répétitions, la seconde partie est optionnelle /\d{10}/ : répétitions de 10 chiffres
Remarque : On peut bien sûr préciser un intervalle entre deux valeurs {2,3}, mais aussi entre une valeur donnée et plus ab{2,}, abbbbbbbb…

Les métacaractères

La puissance des expressions rationnelles provient de leur capacité à autoriser des alternatives et des quantificateurs de répétition dans le masque. Ils sont encodés dans le masque par des métacaractères, qui ne représentent pas ce qu’ils sont, mais sont interprétés d’une certaine manière.
Doc PHP

On a précédemment vu l’utilisation de ces caractères, comme par exemple les quantificateurs. Voici les différents métacaractères qu’il faut connaître :

# ! ^ $ ( ) [ ] { } | ? + * .

Pour utiliser un métacaractère dans une recherche, il faut l’échapper avec un antislash : \.

Options

Les regex PCRE permettent d’ajouter des options, voici celles que j’utilise le plus :

  • i : la regex sera insensible à la casse, par exemple : /abc/i, ce qui nous donne « abc » ou « ABC »
  • s : le métacaractère « . » fonctionnera aussi pour les retours à la ligne
  • U : mode « ungreedy », cette option permet de préciser que la regex s’arrête le plus tôt possible. Ainsi si on veut par exemple que la regex s’arrête à la première occurrence d’une balise.

Les parenthèses capturantes

Les regex permettent de capturer des portions de chaîne grâce aux parenthèses. Ensuite en PHP par exemple on pourra utiliser la fonction preg_match afin de récupérer ces portions de chaîne. C’est la variable de sortie optionnelle qui permettra de récupérer ses résultats. Elle contiendra alors un tableau : l’index zéro contiendra la chaîne complète correspondant au masque puis chaque index suivant sera rempli par une capture dans l’ordre où elles sont définies.

Ce qui nous donne par exemple :

$str = "abcdef";
$pattern = '/def/';
preg_match($pattern, $str, $matches, PREG_OFFSET_CAPTURE);
echo "<pre>";
print_r($matches);
echo "</pre>";

Et le résultat du script :

Array
(
[0] => Array
(
[0] => def
[1] => 3
)
)

Les regex par l’exemple

Nom Regex Texte à parser
Date au format jj/mm/aaaa ou jj-mm-aaaa /([0-9]{2}[-\/]){2}[0-9]{4}/ 09-05-1992
Adresse email /[A-Za-z0-9-_\.]+@[a-zA-z0-9]+.[a-zA-Z]{2,3}/ test_61@gmail.com
Numéro de téléphone /^0[1-9]([-. ]?[0-9]{2}){4}$/ 02.33.33.54.85
URL /http[s]?:\/\/[A-Za-z0-9\/~\.]*/ http://www.ensicaen.fr/~test/image.png
Balise img /<img(.)*\/>/ <img src=’http://www.google.fr’ alt=’ ‘ />

Tester ses regex

Afin de pouvoir tester ses regex, il existe différents sites, pour ma part j’utilise : regex101.com. On copie colle, le texte que l’on veut récupérer et on teste notre regex en temps réel avec une explication sur les différentes parties de notre regex. Cela peut donc être également intéressant pour débuter avec les regex.

Utilisation d’une regex en PHP pour vérifier un formulaire

Les regex sont très utilisés en PHP, elles peuvent par exemple permettre de vérifier les informations saisies dans un formulaire, notamment grâce à la fonction preg_match :

$regex = "#[A-Za-z0-9-_\.]+@[a-zA-z0-9]+.[a-zA-Z]{2,3}#";
if(preg_match($regex, $_POST['email'])) {
// Adresse mail correct, on peut envoyer le mail
} else {
echo "Adresse mail, incorrect veuillez saisir une adresse correcte.";
}

Cette fonction permet de vérifier l’existence d’une regex dans une chaîne de caractères, ici on vérifie donc que la variable saisie dans un champ input de name email, correspond bien à une adresse mail, si c’est le cas on effectue l’envoi du mail, sinon on affiche une erreur.

Un parser grâce au regex

Enfin, en dernier exemple nous allons réaliser un parser. Ce genre d’outils est utilisé par les forums, pour permettre à un utilisateur de mettre facilement en forme son texte. Par exemple afin de mettre en gras du texte, de le mettre en italique et j’en passe.

Notamment le plus connu des outils, c’est le bbCode.

[b][/b] // texte en gras
[i][/i] // texte en italique
[color=red][/color] // coloré le texte

Afin de pouvoir effectuer ce remplacement, il suffit d’utiliser la fonction preg_replace de php.

$txt = preg_replace('#\[b\](.+)\[/b\]#isU', '<strong>$1</strong>', $txt);
$txt = preg_replace('#\[i\](.+)\[/i\]#isU', '<em>$1</em>', $txt);
$regex = '#\[color=(red|green|blue|yellow|olive|...)\](.+)\[/color\]#isU';
$texte = preg_replace($regex, '<span style="color:$1">$2</span>', $texte);

La fonction prend donc en paramètre la regex qui va nous permettre de cibler ce que l’on veut remplacer, on utilise les parenthèses capturantes. Le second argument sera ce que l’on veut obtenir, c’est-à-dire, notre variable obtenu grâce aux parenthèses entourées de la balise désirée. Enfin le dernier argument est le texte sur lequel on effectue ce remplacement.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *