Expressions Régulières en PHP

Youssef Chahir
GREYC — Université de Caen

Expression régulière :

Une expression régulière, ou regular expression, ou encore expression rationnelle, permet de définir un modèle général, appelé motif de l’expression régulière, au moyen de caractères particuliers, représentatifs d’un ensemble de chaînes de caractères très variées :
  • Vérifier si une saisie faite par un visiteur du site est conforme au format couramment attendu, comme celui d’une adresse e-mail, et, dans le cas contraire, d’afficher un message d’erreur.
  • Ces motifs permettent de rechercher dans un texte s’il existe des occurrences d’un mot ou de retrouver tous les mots qui répondent à tel critère particulier
  • Dans la pratique, ces chaînes proviennent le plus souvent de saisies effectuées dans un formulaire.

Motifs :

Une regex s’apparente à une expression mathématique, car on y trouve des opérateurs, des valeurs et des variables.
  • Les regex permettent de se lancer à la recherche de motifs décrits par la combinaison d’opérateurs et de valeurs.
  • Les fonctions de recherche de motifs du PHP retournent vrai si le motif a été trouvé dans une chaîne de caractères, elles permettent aussi d’extraire de cette chaîne la sous chaîne qui correspond au motif et de la modifier.
  • Les motifs sont décrits par ces trois caractéristiques :
    • les caractères, chaînes ou classes de caractères qui les composent
    • leur nombre d’apparition
    • leur position
    • les alternatives

Les fonctions PHP:

  • preg_match($motif, $chaine, $matches) : retourne TRUE si le motif $motif est trouvé dans la chaîne $chaine. Le tableau $matches contiendra les sous-chaînes de $chaine vérifiant le motif.
  • preg_replace($motif, $nouvelle, $chaine) : retourne la chaîne $chaine dont les sous-chaînes vérifiant le motif $motif sont remplacées par la chaîne $nouvelle.
  • preg_split($motif, $chaine [, $limit]) : retourne un tableau – d’au maximum $limit éléments – des sous-chaînes de $chaine qui se trouvent séparées par des délimiteurs vérifiant le motif $motif.
Les fonctions preg_match() et preg_replace() sont sensibles à la casse par défaut. Pour les versions insensibles à la casse, utilisez les options appropriées avec les fonctions preg_match() et preg_replace(), ou utilisez les versions alternatives preg_match_all() et preg_replace_callback().

Caractères spéciaux :

Les caractères spéciaux sont ceux qui possèdent une signification particulière aux yeux des règles de construction des motifs des regex.
  • Ces caractères ne peuvent pas être utilisés comme n’importe quel autre, sauf à les précéder d’un antislash \.
  • Ils sont les suivants : ^ . [ ] $ ( ) | * + ? { } \
  • Toutefois ces caractères (sauf ] et -) perdent leur caractère spécial lorsqu’ils sont utilisés entre crochets.
  • Pour despécialiser un caractère, il faut le faire précéder d’un antislash \. A noter qu’en dehors des crochets, le tiret - n’a pas signification particulière.

Synthèse:

Voici une synthèse des motifs avec des caractères spéciaux :
  • [abcdef] : intervalle de caractères, teste si l’un d’eux est présent
  • [a-f] : plage de caractères : teste la présence de tous les caractères minuscules entre ‘a’ et ‘f’
  • [^0-9] : exclusion des caractères de ‘0’ à ‘9’
  • \^ : recherche du caractère ’^’ que l’on déspécialise par l’antislash \
  • . : remplace un caractère
  • ? : rend facultatif le caractère qu’il précède
  • + : indique que le caractère précédent peut apparaître une ou plusieurs fois
  • * : pareil que + Mais le caractère précédent peut ne pas apparaître du tout
  • {i,j} : retrouve une chaîne contenant entre au minimum i et au maximum j fois le motif qu’il précède
  • {i,} : idem mais pas de limite maximum
  • {i} : retrouve une séquence d’exactement i fois le motif qu’il précède
  • ^ : le motif suivant doit apparaître en début de chaîne
  • $ : le motif suivant doit apparaître en fin de chaîne

Exemple :

Validité d'une date:

Dans un formulaire complété par un visiteur, il n’est pas rare que celui-ci indique une date, ne serait-ce que sa date de naissance. Même si une expression régulière peut vous permettre de vérifier si la saisie répond à un format imposé, par exemple JJ/MM/AAAA, elle ne peut vérifier si la date indiquée existe ou si le nombre des jours et celui des mois sont inversés.
  • Utiliser la fonction boolean checkdate(int mois, int jour, int année) :
<?php
if(isset($_POST["date"]))
{
    
$date=$_POST["date"];
    
$tabdate=explode("/",$date);
    if(!
checkdate($tabdate[1],$tabdate[0],$tabdate[2]) ) {
        echo 
"La date $date n'est pas valide. Recommencez! <hr />";
    }
    else {
        echo 
"<h3> La date $date est valide. Merci!</h3>";
    }
}
?>

Filtre une variable avec un filtre spécifique :

La commande php filter_var (variable, filtre, options) — permet de filtrer une variable avec un filtre spécifique. Elle retourne les données filtrées, ou FALSE si le filtre échoue.
  • variable : Spécifie la variable à filtrer
  • filtre (facultatif): Identifiant du filtre à utiliser (a hef="https://www.oujood.com/php/php_ref_filter.php">Voir la référence complète des filtres php)
  • options (facultatif) : Tableau associatif d'options ou des drapeaux. Si le filtre accepte les options, les drapeaux peuvent être fournis dans le champ "flags" du tableau.
  • Exemple :
    • filter_var("exemple@example.com", FILTER_VALIDATE_EMAIL)

Fonctions utiles:

<?php
//fonctions utiles
//Un email
function controlerEmail($valeur) {
    if(
filter_var($valeurFILTER_VALIDATE_EMAIL))return true;
    else return 
false;
}
// Une date
function controlerDate($valeur) {
    if (
preg_match("/^(\d{1,2})[\/|\-|\.](\d{1,2})[\/|\-|\.](\d\d)(\d\d)?$/"$valeur$regs)) {
        
$jour = ($regs[1] < 10) ? "0".$regs[1] : $regs[1]; 
        
$mois = ($regs[2] < 10) ? "0".$regs[2] : $regs[2]; 
        if (
$regs[4]) $an $regs[3] . $regs[4];
              if (
checkdate($mois$jour$an)) return true;
        else return 
false;
    }
    else return 
false;
}
function 
controlerAlphanum($valeur) {
    if (
preg_match("/^[\w|\d|\s|'|\"|\\|,|\.|\-|&|#|;]+$/"$valeur)) return true;
    else return 
false;
}   
function 
controlerNum($valeur$strict=false) {
    if (
$strict) {
        if (
ereg("^[0-9]+$"$valeur)) return true;
        else return 
false;
    }
    else if (
preg_match("/^[\d|\s|\-|\+|E|e|,|\.]+$/"$valeur)) return true;
    else return 
false;
}   
// Un numéro de téléphone
function controlerTel($valeur) {
    if (
preg_match('#(0|\+33)[1-9]( *[0-9]{2}){4}#'$valeur)) return true;
    else return 
false;
}   
//Code Postal
function controlerCP($valeur) {
    if ( 
preg_match ("~^[0-9]{5}$~",$valeur))
        return 
true;
    else
        return 
false;
}  
?>