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.
Initiation et basique des Regex
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 : \.
Les options des expressions régulières
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 expressions régulières
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 (j’ai d’ailleurs fait un article pour du javascript sur le sujet), 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 PHP 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.