Principe
- Les expressions régulières sont des modèles créés à l'aide de caractères ASCII permettant de manipuler des chaînes de caractères et de trouver les portions de la chaîne correspondant au modèle.
- Ce système vient de POSIX (norme à l'origine sous Unix). De nombreux scripts sous UNIX les utilisent.
- Les expressions régulières permettent de rechercher des occurrences (= suite de caractères correspondant à ce que l'on recherche) grâce à une série de caractères spéciaux. L'expression régulière en elle-même est donc une chaîne de caractère contenant des caractères spéciaux et des caractères standards
Domaines d'application
- Vérifier la validité des chaînes de caractères ( saisie dans un formulaire : email, entrée chiffrée, entrée texte, etc...)
- Extraire des parties bien précises d'une chaîne, d'un texte, d'une page...
- Modifier une date au format us (05-30-1977) au format fr notamment (30/05/1977)
- Remplacer automatiquement toutes les adresses "http://" par des liens cliquables (cf forums, guestbook … )
- Pour créer son propre langage simplifié à partir de la norme HTML, bbCode ([b][/b]...)
Exemple
<?php
if (preg_match("** REGEX **", "string’’)) { 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';
} ?> !(((https?|ftp)://(w{3}\.)?)(?<\!www)(\w+-?)*\.([a-z]{2,6}))!
Utilisation
On peut choisir n'importe quel caractère spécial comme délimiteur, dans les exemples suivant on prendra par convention le délimiteur !
Les délimiteurs permettent d'utiliser des options :
'!MA
REGEX!Options
Exemple : les expressions régulières sont sensibles à la casse, on peut changer son comportement avec l'option i
Chaîne | Test | Résultat |
---|---|---|
J'ai une jolie voiture | !jolie! |
vrai |
J'ai une jolie voiture | !JOLIE! |
faux |
J'ai une jolie voiture | !JOLIE!i |
vrai |
Opérateurs
La barre oblique | signifie ou dans les regex !bleu|rouge!
Les regex permettent des recherches précises et très structurés, dans
les exemples précédant le mot pouvait se trouver n’importe ou dans la
chaîne
^ (accent circonflexe) : indique le début d'une chaîne. !^Debut!
$ (dollar) : indique la fin d'un chaîne. !fin$!
Entre crochets = la classe de caractères. Cela signifie qu'une
des lettres à l'intérieur peut convenir : !gr[aio]s!
notre
regex reconnaît donc gras gros et gris
Plages de caractères
Grâce au symbole - (le tiret), on peut autoriser toute une
plage de caractères.
Si on veut que la chaine contienne une lettre on écrira pas :
[abcdefghijklmnopqrstuvwxyz] on peut utiliser les intervalles.
[a-z] ou [a-e] avec les chiffres : [0-9] , [1-8]
On peu combiner les plages aussi : [a-z0-9]. Cela signifie "N'importe
quelle lettre (minuscule) OU un chiffre".
On peut aussi autoriser les majuscules, sans passer par les options :
[a-zA-Z0-9].
Exemple : !<h[1-6]>!
(titres html)
Pour omettre un caractère dans une classe on utilise aussi le
symbole ^
Exemple : ![^0-9]!
(ne contient aucun chiffre)
Quantificateurs
- ? (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" … - * (étoile)
- la lettre est facultative. Elle peut apparaître 0, 1 ou plusieurs fois.
- Ainsi,
!a*!
reconnaît "a", "aa", "aaa", "aaaa" etc... Comme c’est facultatif si a n’y est pas ça renvoi vrai aussi !!! - {n,m}
- ? correspond à {0,1}
- + correspond à {1,}
- * correspond à {0,}
!disques?!
Pour répéter plusieurs lettres on peut utiliser les parenthèses :
!test(test)*!
: reconnaitra testtesttesttesttesttesttesttest...
Métacaractères
les métacaractères qu'il faut connaître sont les suivants :
! ^ $ ( ) [ ] { } ? + * . \
- . (point)
- remplace n'importe quel caractère (unique)
- \ (antislash)
- permet d'échapper un métacaractère (ne pas le prendre en compte)
Exemple
Règles
Les règles pour une adresse email valide :- On a tout d'abord le pseudonyme (au minimum une lettre). Il peut y avoir des lettres minuscules (pas de majuscules), des chiffres, des points, des tirets et des underscores "_".
- Il y a ensuite une arobase : @
- Ensuite il y a le nom du fournisseur d'accès. Pour ce nom, que des minuscules, des chiffres, des tirets, des points et des underscores.
- Enfin, il y a l'extension (comme ".fr"). Cette extension comporte un point, suivi de 2 à 3 lettres (minuscules).
Construction
!^$!
Tout d’abord une fin et un début de chaine- Ensuite, on a des lettres, chiffres, tirets, points,
underscores, au moins une fois. On utilise donc la classe
[a-z0-9._-]
à la suite de laquelle on rajoute le signe + :!^[a-z0-9._-]+$!
- l'arobase :
!^[a-z0-9._-]+@$!
- Puis, encore une suite de lettres, chiffres, points, tirets au
moins 2 fois :
!^[a-z0-9._-]+@[a-z0-9._-]{2,}$!
- Pour le point de .fr .com … :
!^[a-z0-9._-]+@[a-z0-9._-]{2,}\.$!
- Enfin l’extension (en minuscules) :
!^[a-z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,6}$!
Recherche / remplacement
preg_replace($masque, $remplacement, $chaine);
Chaque fois qu’on utilisera des parenthèses, ça va créer une "variable"
contenant ce qu'elles entourent.
Exemple : !\[b\](.+)\[/b\]!
Les parenthèses ici sont
inutiles dans le cas d ’une recherche simple, mais pour faire du
rechercher remplacer ca va être utile.
A chaque parenthèse ouverte dans une regex, php va créer une variable
appelée $1 (pour la première parenthèse), $2 pour la seconde etc…
Exemple
<?php $texte = preg_replace('!<b>(.+)</b>!i', '<strong>$1</strong>', $texte); ?>Premier paramètre la Regex. Attention chaque parenthèse va créer une variable ($1, $2 etc...)
On ajoute l'option "i" pour que le code fonctionne aussi avec des majuscules (<B></B>)
Ensuite on indique le texte de remplacement : "<strong>$1</strong>"
Enfin, dernier paramètre, c'est le texte dans lequel on fait notre recherche / remplacement.
Règles
Avec plusieurs parenthèses, pour savoir le numéro d'une parenthèse il suffit de les compter dans l'ordre de gauche à droite.Exemple
!(anti)co(nsti)(tu(tion)nelle)ment!
Il y a 4 parenthèses dans cette regex (donc $1, $2, $3 et $4). La parenthèse numéro 3 ($3) contient "tutionnelle", et la parenthèse $4 contient "tion"
C ’est l'ordre dans lequel les parenthèses sont ouvertes qui est important.
Les regex sont limitées à 99 parenthèses capturantes dans une Regex $99 est donc la valeur maximum.
Il faut savoir qu ’une variable $0 est toujours créée, elle contient toute la Regex. Sur le même exemple que tout à l'heure : !(anti)co(nsti)(tu(tion)nelle)ment!
$0 contient "anticonstitutionnellement".
Pour ne pas qu ’une parenthèse soit capturante (=pour simplifier les comptes, ou ou si la regex est très complexe), il faut qu'elle commence par un point d'interrogation suivi d'un deux points ?:
!(anti)co(?:nsti)(tu(tion)nelle)ment!
Options
- i : pour accepter les majuscules comme les minuscules
- s : pour que le "point" fonctionne aussi pour les retours à la ligne (pour que le texte puisse être en gras sur plusieurs lignes)
- U : le U majuscule est une option qui signifie "Ungreedy" ("pas gourmand"). "Ce texte est <b>important</b>, il faut me <b>comprendre</b> !
Exercice
Le parser va servir à transformer le texte rédigé par un visiteur (forum / chat / livre d ’or...), en un texte inoffensif mais qui accepte aussi du bbCode !
[b][/b] : pour mettre du texte en gras.
[i][/i] : pour mettre du texte en italique.
[color=red][/color] : pour colorer le texte
Nous ferons en sorte de remplacer aussi automatiquement les URL (http://) par des liens cliquables.