preg_match($pattern, $subject, $matches) vérifie si une chaîne correspond à une expression régulière. Elle renvoie 1 en cas de correspondance et 0 sinon, et remplit $matches avec ce qu'elle a trouvé : preg_match('/\d+/', 'Order 4521 shipped', $m) renvoie 1 et met $m[0] à "4521".
Le motif est une chaîne entourée de délimiteurs, en général /.../, suivie de modificateurs comme i. Écrivez les motifs entre guillemets simples : entre guillemets doubles, PHP développe d'abord $name et des échappements comme \x41 ou \101, si bien que le moteur de regex peut recevoir un motif différent de celui que vous avez tapé.
Groupes de capture
Les parenthèses dans un motif capturent la partie de la chaîne qu'elles trouvent. $m[0] est la correspondance complète, $m[1] le premier groupe, $m[2] le second, comptés par parenthèse ouvrante depuis la gauche.
Groupes nommés
(?<name>...) donne un nom à un groupe. La valeur est rangée sous le nom et sous son numéro, donc le code qui lit le résultat ne casse pas quand quelqu'un ajoute un groupe plus tôt dans le motif.
Trouver toutes les correspondances avec preg_match_all
preg_match_all() continue à chercher après la première correspondance et renvoie le nombre de correspondances. Par défaut, $m[0] contient toutes les correspondances complètes et $m[1] toutes les valeurs du premier groupe. Avec PREG_SET_ORDER, vous obtenez plutôt un tableau par correspondance, plus facile à parcourir.
Valider une saisie : ancres, numéros de téléphone, codes postaux
Pour une validation, le motif doit correspondre à toute la chaîne, commencez-le donc par ^ et terminez-le par $. Un piège : $ correspond aussi avant un saut de ligne final, donc '/^\d+$/' accepte "123\n". Ajoutez le modificateur D, ou utilisez \z, qui ne correspond qu'à la toute fin.
Pour les adresses email, une regex rejette des adresses valides ou en accepte d'invalides. Utilisez plutôt filter_var($email, FILTER_VALIDATE_EMAIL) (voir filter_var()).
Le modificateur u pour l'UTF-8 et le texte japonais
Sans le modificateur u, un motif travaille sur des octets. Un caractère japonais fait trois octets en UTF-8, donc . correspond à un tiers de caractère et les longueurs sont fausses. Avec u, le motif travaille sur des caractères et vous pouvez utiliser des classes de propriétés Unicode.
u valide aussi la chaîne : si elle n'est pas en UTF-8 valide, preg_match() renvoie false au lieu de chercher une correspondance.
Échapper une saisie utilisateur avec preg_quote
Des caractères comme ., +, ?, ( et / ont un sens particulier dans un motif. Si une partie du motif vient d'une variable, comme un terme de recherche, passez-la dans preg_quote() avec le délimiteur en second argument, sinon 1+1 correspondra à 11 et un / non échappé cassera le motif.
Un motif invalide ne lève pas d'exception. PHP affiche un warning et preg_match() renvoie false :
Warning: preg_match(): No ending delimiter '/' found in /path/to/index.php on line 3
Vérifiez donc === false (ou preg_last_error_msg()) quand le motif est construit à l'exécution. Pour une simple recherche de sous-chaîne sans motif, str_contains() est plus rapide et plus claire. Pour modifier le texte trouvé, utilisez preg_replace().
Questions fréquentes
Que renvoie preg_match en PHP ?
1 si le motif correspond, 0 sinon, et false si le motif lui-même est invalide. Comme 0 et false sont tous deux évalués à faux, comparez avec === 1 quand vous devez distinguer un motif en échec d'une absence de correspondance.
Comment obtenir le texte trouvé par preg_match ?
Passez un troisième argument : preg_match('/(\d+)/', 'Order 4521', $m). Ensuite $m[0] est la correspondance complète et $m[1] le premier groupe de capture, tous deux "4521" ici. Avec un groupe nommé (?<id>\d+), la valeur est aussi dans $m['id'].
Quelle est la différence entre preg_match et preg_match_all ?
preg_match() s'arrête à la première correspondance. preg_match_all() trouve toutes les correspondances, renvoie leur nombre et remplit $matches avec toutes : preg_match_all('/\d+/', 'a1 b22 c333', $m) renvoie 3 et $m[0] vaut ["1", "22", "333"].
Comment utiliser preg_match avec du texte japonais ou un autre texte UTF-8 ?
Ajoutez le modificateur u : preg_match('/^.{3}$/u', '日本語') renvoie 1. Sans u, PHP traite la chaîne comme des octets, donc . correspond à un octet d'un caractère de 3 octets. Avec u, vous pouvez aussi utiliser des classes Unicode comme \p{Han}, \p{Hiragana} et \p{Katakana}.
Comment vérifier qu'une chaîne ne contient que des chiffres en PHP ?
preg_match('/^\d+$/D', $s) ou, sans regex, ctype_digit($s). Le modificateur D (ou \z au lieu de $) compte : un simple $ accepte aussi un saut de ligne final, donc "123\n" passerait.