Les expressions régulières.
Réponse AJAX

Présentation générale

Une expression régulière permet de représenter un groupe sémantique de chaînes de caractères, à la manière des caractères jokers * et ? (utilisés dans le LIKE de SQL ou dans les lignes de commandes DOS et Shell).

Par exemple, l'expression régulière qui représente les dates au format MySQL est :
\d\d\d\d-\d\d-\d\d (où \d représente n'importe quel chiffre, et - représente le cacactère correspondant).

J'améliore l'exemple précédent en indiquant que le mois va de 01 à 12, que je vais détailler de la façon suivante :
0 suivi de 1 à 9, ou 1 suivi de 0 à 2
Traduit en expression régulière, cela donne :
\d\d\d\d-(0[1-9]|1[0-2])-\d\d

Ces expressions permettront de vérifier des syntaxes. L'utilisation la plus courante sera de valider les saisies dans les contrôles graphiques, mais on peut faire des choses plus sophistiquées avec, comme vérifier la syntaxe d'un langage.

Beaucoup de langages de programmation intègrent, en natif ou sous forme de modules, les fonctions ou méthodes nécessaires pour manipuler les expressions régulières.

Utiliser les expressions régulières en PHP

La fonction preg_match

En PHP, preg_match sera la fonction la plus utilisée pour vérifier les expressions régulières.

Voici un exemple simple d'utiliation, basé sur le pattern du paragraphe précédent :

Remarquez les ~ (tilde) qui, pas très utiles, font toutefois partie de la syntaxe : ce sont les délimiteurs de l'expression régulière. On peut placer des options après le deuxième ~, par exemple l'option i qui signifie case insensitive :

On peut utiliser le caractère de notre choix comme délimiteur. Utilisez un caractères qui a peu de chance d'apparaître dans vos expressions régulières, car vous serez obligé de l'échapper :

Les résultats renvoyés par preg_match

preg_match renvoie :

Une bonne façon d'utiliser la fonction preg_match serait donc :

Grâce à la différence entre false et 0, on peut distinguer si le problème vient du pattern (il n'est pas une expression régulière valide) ou de la chaîne testée (elle ne colle pas au pattern).

Les autres fonctions PHP qui manipulent les expressions régulières

Les autres fonctions utilisant les expressions régulières permettent de faire des recherches multiples, des chercher/remplacer, des découpages de chaines, etc.

La syntaxe des expressions régulières

Les opérateurs utilisés dans les expressions régulières sont :

CaractèreRôle
[ ]Les crochets définissent une liste de caractères autorisés (ou interdits si la liste commence par ^). Par exemple :
  • [a-zA-Z] représente toutes les lettres non accentuées.
  • [a-zéèùôûîçàïëöêæœ] représente toutes les minuscules de la langue française
  • [^123] représente tout sauf 1, 2 et 3.
( )
  • Les parenthèses servent, comme en mathématiques, à gérer les priorités. Par exemple :
    temps (nuageux|gris|couvert)
    il fait (très ){1,3}beau
  • On les appelle également des parenthèses capturantes puisqu'elles stockent leur contenu, on pourra y faire référence ultérieurement (voir plus loin : les parenthèses capturantes).
{ }Nombre de répétitions autorisées de l'élément précédent. Par exemple :
p{3,5} : correspond à ppp, pppp ou ppppp
p{6} correspond à pppppp
p{3,} correspond à ppp, pppp, pppppp, etc.
-Un moins entre deux caractères dans une liste représente un intervalle (par exemple [a-d] représente [abcd]). En dehors de ce contexte, - vaut pour lui-même.
.Le caractère point représente un caractère unique, quelconque.
*Le caractère astérisque indique la répétition indéterminée de l'élément le précédant (0 ou plusieurs).
?Le caractère "point d'interrogation" indique la présence éventuelle de l'élément la précédant (0 ou 1).
|Choix : élément de gauche ou élément de droite (BTS (IG|SIO))
^
  • Placé en début d'expression, il représente le début dela chaîne et signifie donc "chaîne commençant par .. ",
  • Utilisé à l'intérieur d'une liste il signifie "ne contenant pas les caractères suivants...", par exemple [^a] signifie "tout sauf a"
$Placé en fin d'expression il signifie "chaîne finissant par ..."

Les ensembles de caractères que l'on peut représenter dans les expressions régulières sont :

EnsembleRôle
\wCaractère alphanumériques, équivaut à [a-zA-Z0-9_].
\WTout sauf un caractère alphanumérique.
\sUn séparateur (espace, retour chariot, tabulation), équivaut à [ \r\n\t]
\STout sauf un séparateur.
\dUn chiffre [0-9].
\DTout sauf un chiffre.
etc.

Les caractères qui ont besoin d'être échappés car ils ont un rôle particulier : [ ] { } ( ) . * ? | \ ^ $ +
Et, dans certains cas : -
$ doit être échappé d'office dans une chaîne PHP entre double cotes. Il faut donc l'échapper une deuxième fois pour l'expression régulière, et échapper son échappement. Rien compris ? Suivez l'exemple (Nd2017 : il vaut mieux entourer les expressions régulières de guillemets simples, pour limiter le nombre d'échappements) :
"/global \\\$var/"

Codes couleur : votre expression régulière est juste quand :

Ecrivez l'expression régulière qui représente les codes postaux (5 chiffres quelconques)

Votre réponse n°1

Ecrivez l'expression régulière qui représente les numéros de téléphone au format 0# ## ## ## ##, avec ou sans espaces.

Votre réponse n°2

Ecrivez l'expression régulière qui représente les numéros de téléphone français tous formats (0# ## ## ## ## ou +33 # ## ## ## ##, où le premier # n'est pas 0)

Votre réponse n°3

Ecrivez l'expression régulière qui représente les adresses électroniques simplifiées, par exemple : laurie-ann3.blanc_84@ma-societe123.fr (le premier caractère du nom et du domaine sera une lettre, le TLD ne contient que des lettres).

Votre réponse n°4

Ecrivez l'expression régulière qui représente les adresses IPv4.

Votre réponse n°5

(Difficile) Ecrivez l'expression régulière qui représente uniquement les dates valides (sauf le 29 février pour les années non bissextiles qui sera toléré). Par exemple le 31 avril sera invalide (2012-04-31), comme le 32 janvier (2012-01-32).

Votre réponse n°6

Les parenthèses capturantes

Lorsqu'on place des parenthèses dans un pattern, le contenu de la parenthèse va être capturé pour être réutilisé plus loin dans le même pattern, ou pour être renvoyé comme 'résultat' de la fonction.

Premier cas - réutiliser la partie capturée plus loin dans le pattern (référence arrière)

Je veux vérifier la chaîne for ($i=0 ; $i<10 ; $i++) où $i peut être n'importe quelle variable valide. J'utilise l'expression régulière suivante :
^for \(\$([a-z][a-z0-9_]*)=0 ; \$\g{-1}<10 ; \$\g{-1}++\)$

Rien compris ? Je décompose. Je pars de la chaîne d'origine :
for ($i=0 ; $i<10 ; $i++)

J'échappe les caractères spéciaux ( $ + ) pour rendre l'ensemble compatible avec une expression régulière :
for \(\$i=0 ; \$i<10 ; \$i\+\+\)

Je contrains le début de la chaîne et la fin de la chaîne ^ $ pour ne rien tolérer ni avant ni après :
^for \(\$i=0 ; \$i<10 ; \$i\+\+\)$

Je remplace le premier i par un bout d'expression représentant les variables valides, le tout dans une parenthèse capturante :
^for \(\$([a-z][a-z0-9_]*)=0 ; \$i<10 ; \$i\+\+\)$

Je remplace les i suivants par \g{-1} qui fait référence au contenu de la parenthèse capturante précédente :
^for \(\$([a-z][a-z0-9_]*)=0 ; \$\g{-1}<10 ; \$\g{-1}\+\+\)$

Ecrivez l'expression régulière qui valide echo "bonjour"; et echo 'bonjour'; mais qui ne valide pas echo "bonjour';
(Remarque : pour les tests en direct de ce TP, javascript ne connaissant par la syntaxe \g{-1}, utilisez la syntaxe \1 qui représente "la première parenthèse capturante")

Votre réponse n°7

Ecrivez l'expression régulière qui valide $variable='bonjour'; echo $variable; quelques soient les cotes utilisés (simples ou doubles) et quel que soit le nom de la variable.

Votre réponse n°8

Deuxième cas - renvoyer le contenu de la (ou des) parenthèse(s) capturante(s) comme 'résultat(s)' de la fonction

Par exemple, dans le fichier httpd.conf, je veux savoir sur quel port Apache est à l'écoute. Voici l'extrait correspondant du httpd.conf :

# Listen: Allows you to bind Apache to specific IP addresses and/or # ports, instead of the default. See also the # directive. # # Change this to Listen on specific IP addresses as shown below to # prevent Apache from glomming onto all bound IP addresses. # #Listen 12.34.56.78:80 Listen 80

Je dois chercher : \sListen (\d*)\s. Remarquez que si je ne commence pas par un \s, je risque de tomber sur le Listen qui est donné en commentaire.

Je tape le code suivant qui effectue cette recherche et récupère, en résultat, le contenu de la parenthèse capturante :

Initiation à l'aspiration de site : sur le même modèle que pour httpd.conf, et en utilisant le code suivant qui permet de charger une page Web, écrivez l'expression régulière (ligne 5) qui permet de trouver le titre du film à cette adresse :
http://www.allocine.fr/film/fichefilm_gen_cfilm=143026.html

Votre réponse n°9

Vérifiez, pour un autre film quelconque, que le titre est bien extrait par votre code précédent. Collez ici l'URL du film sur lequel vous avez fait le test.

Votre réponse n°10

Utiliser les expressions régulières en Javascript

En Javascript, la syntaxe des expressions régulières est très légèrement différente. En effet, on n'utilise pas les guillemets. La méthode qui permet de tester une expression régulière est test(). Voici comment on fera pour tester une date :

Au lieu d'entourer l'expression régulière avec des slashes, on peut utiliser librement n'importe quel caractère. L'intérêt est de changer de caractère si on doit utiliser beaucoup de slashe à l'intérieur de la chaîne, pour éviter d'avoir à les échapper. Par exemple, voici l'expression régulière qui cherche <br />, remarquez que le slashe n'est pas échappé :

La même chose en PHP (remarquez l'échappement) :

Pour le formulaire suivant, écrivez la fonction valide() qui vérifie que :

<form name=form_inscription>
login : <input name=login><br>
pwd : <input name=pwd1><br>
confirm pwd : <input name=pwd2><br>
mél : <input name=mail><br>
tél : <input name=tel><br>
Date naissance (jj/mm/aa) <input name=naissance><br>
<input type=submit>
</form>
Votre réponse n°11