Les expressions régulières constituent un système très puissant et très rapide pour faire des recherches dans des chaînes de caractères (des phrases, par exemple).
C'est une sorte de fonctionnalité Rechercher / Remplacer très poussée, dont vous ne pourrez plus vous passer une fois que vous saurez vous en servir.
Les expressions régulières vont nous permettre d'effectuer des recherches et des remplacements poussés dans des textes.
Voici quelques exemples pratiques de ce que vous serez en mesure de faire.
- Vérifier automatiquement si l'adresse e-mail entrée par le visiteur a une forme valide (comme « dupont@free.fr »).
- Modifier une date que vous avez au format américain (08-05-1985) pour la mettre dans le bon ordre en français (05/08/1985).
- Remplacer automatiquement toutes les adresses « http:// » par des liens cliquables, comme cela se fait sur certains forums.
- Ou encore créer votre propre langage simplifié à partir du HTML, comme le fameux bbCode ([b][/b]…).
PHP propose donc de choisir entre POSIX et PCRE.
Pour ma part, le choix est tout fait : nous allons étudier PCRE.
Rassurez-vous, ce n'est pas beaucoup plus compliqué que POSIX, mais ça a l'avantage d'être très rapide.
Et à notre niveau de PHP, ce qui nous intéresse justement c'est la rapidité.
Il existe deux types d'expressions régulières, qui répondent aux doux noms de :
- POSIX : c'est un langage d'expressions régulières mis en avant par PHP,
qui se veut un peu plus simple que PCRE (ça n'en reste pas moins assez complexe).
Toutefois, son principal et gros défaut je dirais, c'est que ce « langage » est plus lent que PCRE ;
- PCRE : ces expressions régulières sont issues d'un autre langage (le Perl).
Considérées comme un peu plus complexes, elles sont surtout bien plus rapides et performantes.
Nous avons donc choisi PCRE.
Il existe plusieurs fonctions utilisant le « langage PCRE » et qui commencent toutes par preg_ :
- preg_grep ;
- preg_split ;
- preg_quote ;
- preg_match ;
- preg_match_all ;
- preg_replace ;
- preg_replace_callback.
Chaque fonction a sa particularité :
certaines permettent de faire simplement une recherche, d'autres une recherche et un remplacement,
mais leur gros point commun c'est qu'elles utilisent un « langage » identique pour effectuer une recherche.
Lorsque vous aurez appris le langage PCRE, vous pourrez utiliser chacune d'elles sans problème.
Il faut juste savoir que cette fonction renvoie un booléen : VRAI ou FAUX (true ou false en anglais).
Elle renvoie:
true (vrai) si elle a trouvé le mot que vous cherchiez dans la chaîne,
false (faux) si elle ne l'a pas trouvé.
Vous devez lui donner deux informations :
- votre regex (c'est le petit nom qu'on donne à « expression régulière »)
- et la chaîne dans laquelle vous faites une recherche.
Voici par exemple comment on peut s'en servir, à l'aide d'une condition if :
if (preg_match("** Votre REGEX **", "Ce dans quoi vous faites la recherche")){
echo 'Le mot que vous cherchez se trouve dans la chaîne';
}else{
echo 'Le mot que vous cherchez ne se trouve pas dans la chaîne'; }
exemple de REGEX:
#(((https?|ftp)://(w{3}\.)?)(?<\!www)(\w+-?)*\.([a-z]{2,4}))#
Qui veut dire: nous permettre de vérifier que le texte qu'on nous donne corresponde à une adresse email
PS: enlever l'anti-slash devant !www pour que le code fonctionne
Première chose importante à savoir :
une regex (Expression régulière) est toujours entourée de caractères spéciaux appelés délimiteurs.
On peut choisir n'importe quel caractère spécial comme délimiteur,
et pour éviter de tourner en rond trop longtemps, je vais vous en imposer un : le dièse !
Exemple : #Ma regex#
Parce que si on veut, on peut utiliser des options.
On ne va pas parler des options tout de suite car on n'en a pas besoin pour commencer,
mais sachez que ces options se placent après le second dièse,
comme ceci : #Ma regex#Options
if (preg_match(' #guitare|bandjo$# i ', 'J\'aime la guitare.')) {
// le i permet de confondre le mot même si majuscule ou minuscule
// le | veut dire s'il y a le mot guitare OU bandjo
// le $ veut dire s'il y a le mot guitare ou bandjo sont placés à la fin!
// le ^ veut dire s'il y a le mot guitare ou bandjo sont placés au début!
echo 'VRAI';
}else{
echo 'FAUX'; }
Chaîne | Regex | Résultat |
Bonjour petit zéro | #^Bonjour# | VRAI |
Bonjour petit zéro | #zéro$# | VRAI |
Bonjour petit zéro | #^zéro# | FAUX |
Bonjour petit zéro !!! | #zéro$# | FAUX |
Chaîne | Regex | Résultat |
Grâce à ce qu'on appelle les classes de caractères, on peut faire varier énormément les possibilités de recherche.
Tout cela tourne autour des crochets.
On place une classe de caractères entre crochets dans une regex.
Cela nous permet de tester beaucoup de possibilités de recherche à la fois, tout en étant très précis.
Cela signifie « i » OU « o » OU « a ».
Donc notre regex reconnaît les mots « gris », « gros » et « gras » !
Grâce au symbole « - » (le tiret), on peut autoriser toute une plage de caractères.
Mais que dites-vous de la classe [abcdefghijklmnopqrstuvwxyz] ?
Equivalent : [a-z]
Et pour dire que je n'en veux pas ?
Si vous ne voulez PAS des caractères que vous énumérez dans votre classe,
vous devrez placer le symbole « ^ » au début de la classe.
vous le placez à l'intérieur d'une classe,
il sert à dire que vous neVOULEZ PAS de ce qui se trouve à l'intérieur de cette classe.
exemple : #[^0-9]#
Maintenant, je fais chauffer vos cervelles (tableau suivant).
Chaîne | Regex | Résultat |
Cette phrase contient autre chose que des chiffres | #[^0-9]# | VRAI |
cette phrase contient autre chose que des majuscules et des chiffres | #[^A-Z0-9]# | VRAI |
Cette phrase ne commence pas par une minuscule | #^[^a-z]# | VRAI |
Cette phrase ne se termine pas par une voyelle | #[^aeiouy]$# | FAUX |
ScrrmmmblllGnngngnngnMmmmmffff | #[^aeiouy]# | VRAI |
Chaîne | Regex | Résultat |
Les quantificateurs sont des symboles qui permettent de dire combien de fois peuvent se répéter un caractère ou une suite de caractères.
Par exemple,
pour reconnaître une adresse e-mail comme francois@free.fr,
« Elle commence par une ou plusieurs lettres,
suivie(s) d'une @ (arobase),
suivie de deux lettres au moins, elles-mêmes suivies d'un point,
et enfin de deux à quatre lettres (pour le .fr, .com, mais aussi .info)(Eh oui, ça existe !).
#(((https?|ftp)://(w{3}\.)?)(?<\!www)(\w+-?)*\.([a-z]{2,4}))#
Vous devez retenir trois symboles :
- ? (point d'interrogation) : ce symbole indique que la lettre est facultative.
Elle peut y être 0 ou 1 fois.
Ainsi, #a?# reconnaît 0 ou 1 « a » ;
- + (signe plus) : la lettre est obligatoire.
Elle peut apparaître 1 ou plusieurs fois.
Ainsi, #a+# reconnaît « a », « aa », « aaa », « aaaa », etc. ;
- * (étoile) : la lettre est facultative.
Elle peut apparaître 0, 1 ou plusieurs fois.
Ainsi, #a*# reconnaît « a », « aa », « aaa », « aaaa », etc.
Mais s'il n'y a pas de « a », ça fonctionne aussi !Notez que ces symboles s'appliquent à la lettre se trouvant directement devant.
On peut ainsi autoriser le mot « chien », qu'il soit au singulier comme au pluriel, avec la regex #chiens?# (fonctionnera pour « chien » et « chiens »).
Vous pouvez utiliser le symbole « | » dans les parenthèses.
La regex #Ay(ay|oy)*# renverra par exemple vrai pour « Ayayayoyayayayoyoyoyoyayoy » !
C'est le « ay » OU le « oy » répété plusieurs fois, tout simplement !
Autre bonne nouvelle :
vous pouvez mettre un quantificateur après une classe de caractères (vous savez, avec les crochets !).
Ainsi #[0-9]+# permet de reconnaître n'importe quel nombre, du moment qu'il y a au moins un chiffre !
Maintenant, je fais chauffer vos cervelles (tableau suivant).
Chaîne | Regex | Résultat |
eeeee | #e+# | VRAI |
ooo | #u?# | VRAI |
magnifique | #[0-9]+# | FAUX |
Yahoooooo | #^Yaho+$# | VRAI |
Yahoooooo c'est génial ! | #^Yaho+$# | FAUX |
Blablablablabla | #^Bla(bla)*$# | VRAI |
Chaîne | Regex | Résultat |
Explication du tableau.
Les derniers exemples sont très intéressants.
La regex #^Yaho+$# signifie que la chaîne doit commencer et finir par le mot « Yahoo ».
Il peut y avoir un ou plusieurs « o ».
Ainsi « Yaho », « Yahoo », « Yahooo », etc. marchent…
Mais vous ne devez rien mettre avant ni après,
car j'ai indiqué que c'était un début ET une fin de chaîne avec ^ et $.
Enfin, la dernière regex autorise les mots « Bla », « Blabla », « Blablabla », etc.
Je me suis servi des parenthèses pour indiquer que « bla » peut être répété 0, 1 ou plusieurs fois.
Parfois on aimerait indiquer que la lettre peut être répétée quatre fois, ou de quatre à six fois… bref,
on aimerait être plus précis sur le nombre de répétitions.
C'est là qu'entrent en jeu les accolades.
Vous allez voir :
Il y a trois façons d'utiliser les accolades.
- {3} : si on met juste un nombre, cela veut dire que la lettre (ou le groupe de lettres s'il est entre parenthèses) doit être répétée 3 fois exactement.
#a{3}# fonctionne donc pour la chaîne « aaa ».
- {3,5} : ici, on a plusieurs possibilités. On peut avoir la lettre de 3 à 5 fois.
#a{3,5}# fonctionne pour « aaa », « aaaa », « aaaaa ».
- {3,} : si vous mettez une virgule, mais pas de 2e nombre, ça veut dire qu'il peut y en avoir jusqu'à l'infini.
Ici, cela signifie « 3 fois ou plus ».
#a{3,} fonctionne pour « aaa », « aaaa », « aaaaa », « aaaaaa », etc. Je ne vais pas tous les écrire, ça serait un peu long.
Si vous faites attention, vous remarquez que :
- ? revient à écrire {0,1} ;
- + revient à écrire {1,} ;
- * revient à écrire {0,}.
Chaîne | Regex | Résultat |
eeeee | #e{2,}# | VRAI |
Blablablabla | #^Bla(bla){4}$# | FAUX |
546781 | #^[0-9]{6}$# | VRAI |
Chaîne | Regex | Résultat |
 1706