Les fonctions PCRE
Rappel des expressions régulières PCRE
Dans cette partie de cours, nous allons survoler par quelques exemples les fonctions PCRE. Vous trouverez des exemples plus concrets et plus complet dans les pages des fonctions elles-mêmes.
PCRE est l'acronyme de
Perl Compatible Regular Expressions
Les fonctions PCRE
- preg_grep
- preg_quote
- preg_match
- prg_match_all
- preg_replace
- preg_replace_callback
Voilà nous allons travailler directement par l'exemple avec les fonctions PCRE
Une expression régulière PCRE (Perl) contrairement à POSIX utilise des "délimiteurs".
Ces délimiteurs indiquent le début du motif (ou masque) et sa fin. Ils peuvent être suivis d'options.
Voici la forme d'un masque classique:
(' délimiteur | motif | délimiteur, options ')
Le délimiteur peut être un caractère quelconque*, mais en aucun cas le caractère d'échappement antislash '\' ou un alpha-numérique.
Bien que depuis PHP4, les délimiteurs "symétriques" (), [] , {} et <> soient autorisés, il vaut mieux éviter également de les employer, de même que le point d'exclamation "!" qui est employé au niveau des assertions.
Il faut aussi faire attention au jeu de caractères installé sur le serveur qui peut éventuellement poser des problèmes comme avec le symbole "§" par exemple.
Perso, j'utilise le délimiteur `, soit l'accent grave.Libre à vous d'en utiliser un autre en évitant comme cité plus haut un métacaractère.
>>>Cf -> Le délimiteur et les PCRE
Si vous deviez un jour rencontrer le message suivant :
'No ending delimiter found' ou
'Delimiter must be not alphanumeric or backslash'
vous aurez compris que vous devez changer vos délimiteurs.
Les caractères et symboles utilisés avec PCRE ont de similitudes avec POSIX.
Le début et fin de chaîne sont identiques.
(reportez-vous à la page symboles dans la partie Généralités)
Contrairement à POSIX, on n'utilisera pas forcément les classes prédéfinies à l'intérieur de crochets.
Cela pourra rendre la compréhension des expressions régulières moins aisée puisqu'il sera plus difficile d'y détecter les classes de caractères, mais on ne va pas s'éterniser sur cela et on va passer directement aux explications.
Les fonctions PCRE, outre leur grande puissance sont surtout beaucoup plus rapide que les fonctions POSIX. (jusque 4 à 5 fois à motif identique)
Les fonctions PCRE offrent des fonctionnalités bien plus grandes que les POSIX.
Pour n'en citer que les plus courantes, je dirais :
- Plus rapide
- Utilisation des références arrières
- Capture de toutes les occurences
- Rendre un quantificateur non gourmand
- Utilisation des parenthèses non capturantes
- Utilisation d'une foule d'options
- Utilisation d'assertions, masques conditionnels
- Fonctions de callback
- Etc...
Suite sur les pages :
PCRE en pratique
Les + des PCRE
Les PCRE... mise en pratique !
Pour rappel, les motifs sont réalisés au moyen de symboles spécifiques :
[ Symboles ]
Cette partie de cours est identique à celle sur les POSIX en pratique sauf que je vais travailler ici avec la/les
fonction(s) PCRE preg_match, preg_replace
La grande différence réside dans les motifs de recherche qui doivent impérativement être encadrés, délimités.
Voir :
PCRE et
Le délimiteur et les PCRE
Je vais employer l'accent grave `comme délimiteur
Je ne vais pas retaper le blabla de l'autre tuto et on va aller directement à l'essentiel.
Nous utiliserons la fonction
Cf-> preg_match()
1) Un motif simple, une chaîne
<?php
preg_match('`chien`','Mon animal favori est le chien');
?>
Cet exemple renvoie
VRAI (true) car le
motif 'chien' est présent dans la chaîne sujet.
Cet exemple aurait également pu être formulé de cette façon :
<?php
$chaine='Mon animal favori est le chien';
$motif='`chien`';
preg_match($motif,$chaine);
?>
Un autre exemple :
<?php
$chaine='Les Regex par la pratique';
$motif='`regex`';
preg_match($motif,$chaine);
?>
Cet exemple renvoie
FAUX (false) car le
motif 'regex' n'a pas été trouvé dans la chaîne.
Mais si, me direz-vous, il est bien dans la chaîne !
En effet, il est bien là mais l'expression ne l'a pas reconnu.
D'où vient le problème alors ?
Simple... les expressions régulières sont sensibles à la casse.
Regex et regex bien qu'identique dans leur sens littéral sont pourtant deux mots différents dans leur mode d'écriture.
Les fonction PCRE possèdent une série d'option qui permet de gérer différentes situations particulières.
Donc, pour que notre exemple précédent renvoi
VRAI il fallait écrire l'expression, en ajoutant l'option i, comme ceci :
<?php
$chaine='Les Regex par la pratique';
$motif='`regex`i';
preg_match($motif,$chaine);
?>
Vous comprenez que cela dépend effectivement de ce que l'on recherche au niveau de la chaîne de caractères.
En gardant toujours le même exemple, on peut également arriver au même résultat en créant une
alternative (un
OU si vous préférez)
2) L'alternative dans le motif
<?php
$chaine='Les Regex par la pratique';
$motif='`(regex|Regex|REGEX)`';
preg_match($motif,$chaine);
?>
Cette méthode renvoi
VRAI car l'expression trouvera au moins un des éléments donnés au niveau du motif, soit
regex ou
Regex ou
REGEX
Voilà, on garde notre exemple, mais en plus, on veut
afficher le terme trouvé
Les fonctions PCRE permettent d'adjoindre un argument optionnel
Exemple :
<?php
$chaine='La REGEX est un outil formidable';
$motif='`(regex|Regex|REGEX)`';
preg_match($motif,$chaine,$out);
print_r($out);
// affichera : Array ( [0] => REGEX [1] => REGEX )
?>
Cette recherche affichera le mot trouvé soit :
REGEX
3) Etendons la plage de recherche
Rechercher et trouver un terme spécifique comme ci-dessus est utile mais l'utilité des regex serait bien pauvre si elle ne se limitait qu'à ça.
Nous allons créer des motifs qui permettent des recherches tant générale que spécifique en utilisant les symboles de classes, les parenthèses, etc...
Pour rappel :
[ Symboles ]
Exemple : rechercher les voyelles dans une chaine
<?php
$chaine='Les Regex par la pratique';
$motif='`[aeiouy]`';
preg_match($motif,$chaine);
?>
Cet exemple renvoi
VRAI puisque la chaine contient au moins une des voyelles définies dans le motif.
Exemple : toujours avec des lettres on va créer une classe (une plage de caractères)
<?php
$chaine='Les Regex... une merveille !';
$motif='`[a-d]`';
preg_match($motif,$chaine);
?>
Cet exemple renvoi
FAUX puisque la chaine ne contient aucune de lettres définies dans le motif, alphabet de
'a' à
'd'
Exemple : toujours dans la même logique, on va chercher des chiffres
<?php
$chaine='Les Regex... une merveille !';
$motif='`[0-9]`';
preg_match($motif,$chaine);
?>
Cet exemple renvoi
FAUX puisque la chaine ne contient aucun chiffres défini dans le motif, chiffre de
'0' à
'9'
Exemple : on garde nos chiffres, mais on inverse la logique, on va demander de vérifier que la chaîne ne contient pas de chiffres, on demande une négation en somme.
pour créer la négation en utilisant le symbole ^ à l'intérieur de la classe.
<?php
$chaine='Les Regex... une merveille !';
$motif='`[^0-9]`';
preg_match($motif,$chaine);
?>
Cet exemple renvoi
VRAI puisque, effectivement, la chaine ne contient aucun chiffres défini dans le motif.
Exemple : ci-dessous, on demande au motif de ne pas trouver de lettres, tant minuscules que majuscules, dans la chaîne
<?php
$chaine='Les Regex... une merveille !';
$motif='`[^a-zA-Z]`';
preg_match($motif,$chaine);
?>
Cet exemple renvoi
FAUX puisque, effectivement, la chaine contient des lettres définies dans le motif.
4) Parenthèses capturantes
Pour illustrer cet exemple, on va convertir une date MYSQL au format YYYY-MM-DD
Il est bien entendu que ceci n'est qu'un simple test car Mysql est bien capable de reproduire une date au format souhaité sans faire la moindre regex.
Date exemple : 2003-12-25 convertie en 25/12/2003.
<?php
$date='2003-12-25';
$date=preg_replace('`([[:digit:]]{4})-([[:digit:]]{2})-([[:digit:]]{2})`' ,'$3/$2/$1',$date);
echo $date;
// cette fonction affichera 25/12/2003.
?>
Comme vous le constatez, les possibilités sont multiples et il convient de créer son motif selon ce que l'on souhaite et/ou ce que l'on ne souhaite pas.
L'habitude fera que vous sentirez la direction que vous devrez prendre dans la mise en place de votre motif de recherche.
Le même tuto avec les POSIX :
Cf-> Les POSIX
Rédaction Yves Maistriaux :: Mai 2003
Dernière mise à jour :: Décembre 2005