Les répétitions sont spécifiées avec des quantificateurs, qui peuvent être placés à la suite des caractères suivants :
Les quantificateurs généraux précisent un nombre
minimum et maximum de répétitions possibles, donnés
par deux nombres entre accolades, et séparés par une virgule.
Ces nombres doivent être plus petits que 65536, et le premier nombre
doit être égal ou inférieur au second. Par exemple
z{2,4}
accepte "zz
",
"zzz
", ou "zzzz
". L'accolade fermante
n'a pas de signification par elle-même.
Si le second nombre est omis, mais que la virgule est là, cela
signifie qu'il n'y a pas de limite supérieure. Si le second nombre
et la virgule sont omis, le quantificateur correspond au nombre exact de
répétitions attendues. Par exemple :
[aeiou]{3,}
accepte n'importe quelle succession d'au moins 3 voyelles minuscules, tandis
que
\d{8}
n'accepte que 8 chiffres exactement.
Avant PHP 8.4.0, une accolade ouvrante apparaissant dans une position où un quantificateur n'est pas autorisé,
ou qui ne correspond pas à la syntaxe d'un quantificateur, est considérée comme un caractère littéral.
Par exemple, {,6}
n'est pas un quantificateur, mais une chaîne littérale de quatre caractères.
À partir de PHP 8.4.0, l'extension PCRE est livrée avec la version 10.44 de PCRE2,
ce qui permet des motifs tels que \d{,8}
qui sont interprétés comme \d{0,8}
.
De plus, à partir de PHP 8.4.0, les espaces autour des quantificateurs tels que
\d{0 , 8}
et \d{ 0 , 8 }
sont autorisés.
Le quantificateur {0} est autorisé, mais l'expression est alors ignorée.
Par convenance (et pour la compatibilité ascendante), les trois quantificateurs les plus communs ont une abréviation d'un seul caractère :
* |
équivalent à {0,} |
+ |
équivalent à {1,} |
? |
équivalent à {0,1} |
Il est possible de constituer des boucles infinies en créant un sous-masque
sans caractères, mais pourvu d'un quantificateur sans limite
supérieure. Par exemple :
(a?)*
Les versions plus anciennes de Perl et PCRE généraient alors une erreur au moment de la compilation. Cependant, étant donné qu'il existe des situations où ces constructions peuvent être utiles, ces masques sont désormais autorisés. Toutefois, si la répétition du sous-masque ne trouve aucun caractère, la boucle est interrompue.
Par défaut, les quantificateurs sont dits "gourmands", c'est-à-dire,
qu'ils cherchent d'abord à trouver le nombre maximal de
répétitions qui autorisent le succès de la recherche.
L'exemple classique posé par cette gourmandise est la recherche de
commentaires d'un programme en C. Les commentaires apparaissent entre les
séquences /*....*/
et à l'intérieur
de ces délimiteurs, les *
et /
sont autorisés. Appliquer le masque
/\*.*\*/
à la chaîne
/* premier commentaire */ aucun commentaire /* second commentaire */
ne peut réussir, car le masque travaille sur toute la chaîne,
à cause de la gourmandise du caractère .*
.
Cependant, un quantificateur suivi d'un point d'interrogation cesse
d'être gourmand, et au contraire, ne recherche que le nombre
minimum de répétition. Dans ces conditions, le masque
/\*.*?\*/
trouvera bien les commentaires du code
C. La signification des autres quantificateurs n'est pas changée.
Attention à ne pas confondre l'utilisation du point d'interrogation
ici avec son utilisation comme quantificateur lui-même.
À cause de cette ambiguïté, il peut apparaître des situations
où il faut le doubler :
\d??\d
Ce masque va tenter de lire un seul chiffre, mais le cas échéant,
il acceptera 2 chiffres pour permettre à la recherche d'aboutir.
Si l'option PCRE_UNGREEDY est activée, (une option qui n'est pas disponible avec Perl) alors les quantificateurs sont non gourmands par défaut, mais peuvent être rendu gourmands au cas par cas, en ajoutant un point d'interrogation après. En d'autres termes, cette option inverse le comportement par défaut.
Les quantificateurs suivis par +
sont "possessifs". Ils
mangent autant de caractères que possible et ne retournent pas
pour chercher le reste du masque. .*abc
trouvera
"abc"
, tandis que .*+abc
ne le trouvera
pas, car .*+
accapare totalement la chaîne.
Les quantificateurs possessifs peuvent être utilisés pour
accélérer le traitement.
Lorsqu'un sous-masque est quantifié avec un nombre minimum de répétitions, qui soit plus grand que 1, ou avec un maximum de répétitions, le masque compilé aura besoin de plus de place de stockage, proportionnellement au minimum et au maximum.
Si un masque commence par .*
ou .{0,}
et que l'option PCRE_DOTALL
(équivalent en Perl à /s) est
activée, c'est-à-dire en autorisant le remplacement des nouvelles
lignes par un métacaractère, alors le masque est
implicitement ancré, car tout ce qui suit va être
mangé par la première séquence, et se comportera
comme si le masque se terminait par le métacaractère
\A
. Dans le cas où on sait d'avance qu'il
n'y aura pas de caractère de nouvelle ligne, activer l'option
PCRE_DOTALL et commencer
le masque par .*
permet d'optimiser le masque.
Alternativement, on peut utiliser ^
pour ancrer
explicitement le masque.
Lorsqu'un sous-masque capturant est répété, la valeur capturée est la
dernière. Par exemple, après que
(inter[net]{3}\s*)+
ait été appliqué à "internet interne
",
la valeur de la chaîne capturée est "interne
".
Cependant, s'il y a des sous-masques imbriqués, la valeur
capturée correspondante peut l'avoir été lors
des précédentes itérations. Par exemple :
/(a|(b))+/
accepte "aba
" et
la deuxième valeur capturée est "b
".