logo Pierre AULAS
Expressions régulières en php - Pierre Aulas
 Parcours  |   Réalisations  |   Cours  |   Chroniques  |   Divers

Qu'est-ce qu'une expression régulière?

On parle d'« expressions régulières » pour désigner les techniques qui permettent de retrouver des chaines de caractères à l'intérieur d'un texte.

Je fais déjà cela avec la fenêtre "Rechercher/Remplacer" pensent déjà les plus obtus. Les autrs savent qu'on peut mettre dans cette fenêtre "Rechercher" des caractères spéciaux, dans le genre "*isme" quand on cherche tous les mots qui se terminent en "isme", l'étoile désignant ici n'importe quelle chaîne de caractère.

Ce caractère spécial "*" fait parti de ce qu'on appelle les expressions régulières. Mais c'est un peu le degré zéro de l'expression régulière. Si vous avez juste besoin de trouver le mot "lapin", évidement, ce n'est pas peut-être pas la peine d'aller plus loin.
Si en revanche vous voulez transformer toute votre bibliographie, présentée selon la norme française, pour qu'elle apparaisse désormais selon la norme anglaise – le tout en une ligne de code – il va falloir creuser le problème.

Ah ! une dernière précision : les expressions régulières ne sont pas propres à php. Vous retrouverez le même principe dans absolument tous les langages informatiques (même dans Word, c'est vous dire). Ce que vous apprendrez ici vous permettra donc de manipuler des textes sans difficulté quelque soit votre environnement.

Les expressions régulières sont des modèles créés à l'aide de caractères ASCII réservés permettant de manipuler des chaînes de caractères, c'est-à-dire permettant de trouver les portions de la chaîne correspondant à un modèle.
Il s'agit d'un système fort ingénieux (et aussi très puissant) permettant de retrouver un mot, ou une phrase (et même beaucoup d'autres choses en réalité) dans un texte, ressemblant au modèle que l'on a construit...

Comme nous travaillons avec php et non avec Word, voyons donc comment mettre en œuvre les exemples qui seront présentés dans cette partie.

Les fonctions à connaître pour s'exercer aux expressions régulières avec php

ereg (chaîne recherchée, chaîne [,tableau occurrences] )

chaîne recherchée est une expression régulière recherchée à l'intérieur de chaine. La fonction peut stocker les occurrences trouvées dans un tableau : tableau occurences (mais c'est facultatif).
Si des occurrences sont trouvées, ereg() renvoie true, sinon elle retourne false.

ereg_replace ( chaîne recherchée, chaîne remplacement, chaîne texte )

ereg_replace() retourne la chaîne texte passée en arguments avec les occurrences trouvées remplacées par la chaîne de remplacement.

Ex :

$texte = "Le noir roc courroucé que la bise le roule";
print (ereg_replace("e","a",$texte) );
// Renvoi "La noir roc courroucé qua la bisa la roula"

Jusque-là ça ne devrait pas vous poser trop de problèmes[1].

ps : les puristes feront remarquer qu'il y a d'autres fonctions php – comme preg() et preg_replace() – qui permettent d'utiliser les expressions régulières de manière plus puissante encore. Cela dit, commencez avec ereg(), c'est déjà assez ardu comme cela. Par ailleurs, les fonctions preg() utilise une syntaxe légérement différente qui peut vous embrouiller au début. Les exemples et solutions qui suivent ne fonctionnent à coup sûr qu'avec ereg().

Construire une expression régulière

Les expressions régulières permettent de rechercher des occurrences (c'est-à-dire une 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 mêlant caractères spéciaux et caractères standards.

Voyons donc les principaux caractères spéciaux que nous avons à notre disposition.

Indicateur de position

Les symboles ^ et $ indiquent le début ou la fin d'une chaîne, et permettent donc de la délimiter.

Exemples
Masque Séléction
"^Le" chaîne qui commence par "Le"
"repas$" chaîne qui se termine par "repas"
"^repas$" chaîne qui commence et se termine par "repas"
"epa" chaîne contenant la chaîne "epa" (comme dans repas)

Le caractère universel

Le symbole " . " (un point tout bête) indique un caractère quelconque :

"....." : chaîne comprenant 5 caractères (code postal français par exemple)

Les quantificateurs

Les quantificateurs permettent d'indiquer combien de fois une lettre ou un groupe de lettre peut se trouver dans le texte que l'on recherche. L'exemple le plus classique est celui qui consiste à supprimer tout les espaces blancs redondants : ce qui consiste concrétement à rechercher si deux caractères blancs ou plus se suivent et à les remplacer par un seul.

Le quantificateur s'applique toujours au carctère (ou à la suite de caractère) qui le précède.

Quantifier à la louche

Les symboles *, + et ? indiquent respectivement la quantité : "zéro ou plusieurs", "un ou plusieurs", "un ou aucun".

"abc+" : chaîne qui contient "ab" suivie de un ou plusieurs "c" ("abc", "abcc" ...)
"abc*" : chaîne qui contient "ab" suivie de zero ou plusieurs "c" ("ab", "abc" ...)
"abc?" : chaîne qui contient "ab" suivie de zero ou un "c" ("ab" ou "abc")
"^abc+" : chaîne commençant par "ab" suivie de un ou plusieurs "c" ("abc", "abcc" ...)

Quantifier au pouillème près

Les accolades {X,Y} permettent de donner des limites numériques précises à la quantification (le X donne la limite inférieure, le Y donne la limite supérieure).

"abc{2}" : chaîne qui contient "ab" suivie de deux "c" ("abcc")
"abc{2,}" : chaîne qui contient "ab" suivie de deux "c" ou plus ("abcc" etc..)
"abc{2,4}" : chaîne qui contient "ab" suivie 2, 3 ou 4 "c" ("abcc" .. "abcccc")

Notez que le premier nombre de la limite est obligatoire. On écrit "{0,2}", mais pas "{,2}".
Notez également que les symboles vus précédemment "*", "+", et "?" sont équivalents à "{0,}", "{1,}", et "{0,1}".

Définir une séquence de caractères

Les séquence de caractères

Les séquences de caractères permettent de faire porter les quantificateurs non plus sur un seul caractère mais sur plusieurs caractères situés les uns à côté des autres. En d'autre terme, vous pouvez chercher un mot (mais nous verrons plus tard que cela permet de faire un peu plus que cela).

Les parenthèses ( ) permettent de représenter une séquence de caractères.

"a(bc)*" : chaîne qui contient "a" suivie de zéro "bc" ou plus (a, abc, abcbc)

Le choix entre différentes séquences

La barre verticale " | " (dite aussi 'pipe' – prononcez "paillepeu" si vous voulez passer pour un initié) fonctionne comme un opérateur OU

"un|le" : chaîne qui contient "un" ou "le"
"(un|le) chien" : chaîne qui contient "un chien" ou "le chien"
"(a|b)*" : chaîne qui comprend une suite de "a" ou de "b" (voire même qui ne comprend rien du tout)

Le point " . " indique n'importe quel caractère (une fois)

"^.{3}$" : chaîne qui contient 3 caractères

Les crochets [ ] définissent une liste de caractères autorisés (ou interdits). Le signe - permet quand à lui de définir un intervalle. Le caractère ^ après le premier crochet indique quand à lui une interdiction.

"[abc]" : chaîne qui contient indiféremment un caractère "a", "b", ou "c"

"[a-z]" : chaîne qui contient un caractère compris entre "a" et "z" (soit a, b, c, d, e, f, etc. vous les connaissez)

"^[a-zA-Z]" : chaîne qui commence par une lettre de l'alphabet, majuscule ou minuscule
"^[^a-zA-Z]" : chaîne qui ne commence pas par une lettre, ni majuscule ni minuscule

Pour rechercher un caractère faisant partie des caractères spéciaux, il suffit de le faire précéder d'un antislash (sauf entre crochets)
(un antislash doit donc être doublé !)

En effet dans les crochets, chaque caractère représente ce qu'il est. Pour représenter un ] il faut le mettre en premier (ou après un ^ si c'est une interdiction), un - se met en premier ou en dernier.

"[\+?{}.]" : chaîne qui contient un de ces six caractères
"[]-]" : chaîne qui contient le caractère "]" ou le caractère "-"

Voici un tableau récapitulatif des caractères spéciaux utilisés dans les expressions régulières :

Caractères spéciaux
Caractère  Usage
[] Les crochets définissent une liste de caractères autorisés
() Les parenthèses définissent un élément composé de l'expression régulière qu'elle contient
{} Les accolades lorsqu'elles contiennent un ou plusieurs chiffres séparés par des virgules représentent le nombre de fois que l'élément précédant les accolades peut se reproduire (par exemple p{3,5} correspond à ppp, pppp ou ppppp
- Un moins entre deux caractères dans une liste représente un intervalle (par exemple [a-d] représente [abcd])
. Le caractère point représente un caractère unique
* Le caractère astérisque indique la répétition indéterminée de l'élément la précédant
? Le caractère "point d'interrogation indique la présence éventuelle de l'élément la précédant
| Occurrence de l'élément situé à gauche de cet opérateur ou de celui situé à droite (lard|cochon)
^ Placé en début d'expression il signifie "chaîne commençant par ..."
  Utilisé à l'intérieur d'une liste il signifie "ne contenant pas les caractères suivants..."
$ Placé en fin d'expression il signifie "chaîne finissant par ..."

Les classes de caractères

Il peut également être utile de vérifier si une chaîne contient des caractères d'un certain type (numérique, alphanumérique, ...) sans avoir à les énumérer. Pour cela les expressions régulières définissent des classes de caractères, dont la syntaxe est :

[:classe:]

Les classes de caractères sont celles définies par UNIX. Voici un tableau récapitulant certaines de ces classes :

Caractères spéciaux
Nom de la classe  Description
[:alnum:] caractères alphanumériques (équivalent à [A-Za-z0-9])
[:alpha:] caractères alphabétiques ([A-Za-z])
[:blank:] caractères blanc (espace, tabulation)
[:ctrl:] caractères de contrôle (les premiers du code ASCII
[:digit:] chiffre ([0-9])
[:graph:] caractère d'imprimerie (qui fait une marque sur l'écran en quelque sorte)
[:print:] caractère imprimable (qui passe à l'imprimante ... tout sauf les caractères de contrôle)
[:punct:] caractère de ponctuation
[:space:] caractère d'espacement

Voici quelques exemples d'utilisation des classes de caractère dans une expression régulière :

chaîne composée d'un ou plusieurs caractère(s) alphanumérique(s)

"^[:alnum:]+$"

chaîne contenant un caractère de ponctuation ou un caractère d'espacement

"[:punct:]|[:space:]"

Un nombre

"^[:digit:]+$"

Les fonctions de manipulation d'expressions régulières

PHP fournit quelques fonctions de bases permettant de manipuler des chaînes à l'aide d'expressions régulières. Les fonctions ereg() et eregi()

La fonction ereg() dont la signature est la suivante : Booleen ereg(chaîne modele,chaîne texte[,tableau occurrences]) permet d'évaluer le texte passé en argument grâce au modèle (qui est une expression régulière) et stocke toutes les occurrences dans un tableau passé optionnellement en paramètre. Lorsque la fonction trouve des occurrences, elle renvoie true, sinon elle retourne false.

La fonction eregi() dont la signature est la suivante : Booleen eregi(chaîne modele,chaîne texte[,tableau occurrences]) effectue le même travail que sa consoeur ereg(), à la différence près qu'elle n'est pas sensible à la casse (pas de différenciation minuscules/majuscules)

<?
$fp = fopen("http://www.commentcamarche.net","r"); //lecture du fichier
while (!feof($fp)) { //on parcoure toutes les lignes
$page .= fgets($fp, 4096); // lecture du contenu de la ligne
}

$titre = eregi("<title>(.*)</title>",$page,$regs); //on isole le titre
/* Le titre commence par <title>,
puis contient n'importe quelle chaîne,
et se termine par </title> */
echo $regs[1]; // on retourne la premiere occurrence trouvée
// Les occurrences se trouvent entre parenthèses
// $regs[0] renvoie toute la chaîne
fclose($fp);

?>

Les fonctions ereg_replace() et eregi_replace()

La fonction ereg_replace() dont la signature est la suivante : chaîne ereg_replace(chaîne modele,chaîne remplacement,chaîne texte) Permet de retourner la chaîne texte passée en arguments avec les occurrences trouvees remplacées par la chaîne de remplacement. Pour utiliser les occurrences correspondant au modele dans la chaîne de remplacement, il suffit d'utiliser des parenthèses dans la chaîne modele, puis de faire référence à ces éléments dans la chaîne de remplacement en utilisant deux signes antislash suivi d'un numéro identifiant l'élément entre 0 et 9 (les numéros sont donnés par ordre d'imbriquement, puis de gauche à droite, le zéro représente la chaîne entière). Le code suivant remplace Toto par Toti Toto... inutile mais formateur.

$Texte = "Bienvenue a Toto dans le mondes des expressions régulières";

$Texte = ereg_replace("To(to)","\\1ti \\0",$Texte);

Le code suivant (utilisation avancée des expressions régulières) remplace un URL par un hypertexte HTML (il remplace toute suite de caractères de ponctuations et alphanumériques commençant par http://, ou ftp:// par le même texte (sans le http://) entre balises HTML hypertexte...) :

$Texte = "Bienvenue sur http://www.commentcamarche.net cher ami";

$Texte = ereg_replace("(http://)(([[:punct:]]|[[:alnum:]])*)", "<a href=\"\\0\">\\2</a>",$Texte);

La fonction eregi_replace() dont la signature est la suivante : chaîne eregi_replace(chaîne modele,chaîne remplacement,chaîne texte) effectue le même travail que sa consoeur ereg_replace(), à la différence près qu'elle n'est pas sensible à la casse (pas de différenciation minuscules/majuscules).

La fonction split()

La fonction split() possède la syntaxe suivante :

tableau split (chaîne expression, chaîne texte [, entier limite])

La fonction split() retourne un tableau à partir d'une chaîne et d'une expression régulière. La limite, optionnelle permet de limiter la taille du tableau retourné. Dans ce cas le dernier élément du tableau contient le reste de la chaîne. Si une erreur se produit, split retourne 0.

<?
// découpe une phrase en un tableau de mots
// on utilise split au cas ou plusieurs espaces séparent les mots
$phrase = "Ceci est une phrase avec trois espaces ici";

$tableau_mots = split(" +",trim($phrase)); // un espace ou plus
?>

La fonction sql_regcase()

La fonction sql_regcase() possède la syntaxe suivante :

chaîne sql_regcase (chaîne texte)

Elle retourne une expression régulière qui représente la chaîne passée en paramètre sans tenir compte de la case. Chaque caractère de la chaîne est representé entre crochets, avec deux caractères à l'intérieur un en majuscule et l'autre en minuscule, ou le cas échéant deux fois le même caractères.

<?
echo sql_regcase("un test");

// affiche [Uu][Nn][ ][Tt][Ee][Ss][Tt]
?>

Cette fonction permet de générer une chaîne non sensible à la casse, pour les expressions régulières dans les bases de données par exemple. Dans MySQL lorsque vous utilisez la fonction REGEXP (au lieu de LIKE) la recherche est sensible à la casse. La solution est donc de générer une chaîne non sensible à la casse à l'aide de sql_regcase.

<?
$motclef = sql_regcase("motclef");

$sql = "SELECT * from table WHERE champ REGEXP \"[[:<:]]$motclef[[:>:]]\"";

// selectionne tous les enregistrements de la table table, contenant le MOT motclef
?>

Haut de page

Note 1. La phrase que nous utilisons pour les exemples est extraite du poème suivant.

MALLARME (Stéphane), Tombeau de Verlaine, janvier 1897.

Le noir roc courroucé que la bise le roule
Ne s'arrêtera ni sous de pieuses mains
Tâtant sa ressemblance avec les maux humains
Comme pour en bénir quelque funeste moule.

Ici presque toujours si le ramier roucoule
Cet immatériel deuil opprime de maints
Nubiles plis l'astre mûri des lendemains
Dont un scintillement argentera la foule.

Qui cherche, parcourant le solitaire bond
Tantôt extérieur de notre vagabond -
Verlaine ? Il est caché parmi l'herbe, Verlaine

À ne surprendre que naïvement d'accord
La lèvre sans y boire ou tarir son haleine
Un peu profond ruisseau calomnié la mort.

Si cela vous plaît, vous pouvez en lire d'autres sur le site de l'ABU qui diffuse, depuis des années déjà, quelques jolis textes de la littérature française.

Haut de page
Plan du site  |  Mentions légales  |  Crédits  |  Aide