Une assertion est un test sur les caractères suivants ou
précédents celui qui est en cours d'étude. Ce
test ne consomme pas de caractères (ie, on ne déplace
pas le pointeur de caractères). Les assertions simples sont
codées avec \b, \B,
\A, \Z, \z,
^ et $, et sont décrites
dans les séquences d'échappement.
Il existe cependant des types d'assertions plus complexes, codées sous la forme
de sous-masques. Il en existe deux types : celles qui travaillent
au-delà de la position courante, et celles qui
travaillent en-deçà.
Une assertion se comporte comme un sous-masque, hormis le fait qu'elle
ne déplace pas le pointeur de position. Les assertions avant
commencent par (?= pour les assertions positives, et
par (?!, pour les assertions négatives. Par exemple :
\w+(?=;)
s'assure qu'un mot est suivi d'un point-virgule,
mais n'inclut pas le point virgule dans la capture et foo(?!bar)
trouve toutes les occurrences de "foo" qui ne sont pas suivies par "bar".
À noter que,
(?!foo)bar
en est proche, mais ne trouve pas une
occurrence de "bar" qui soit précédée
par quelque chose d'autre que "foo"; il
trouve toutes les occurrences de "bar",
quel que soit ce qui le précède, car l'assertion
(?!foo)
est toujours vraie quand les trois caractères suivants sont
"bar". Une assertion arrière est ici
nécessaire.
Les assertions arrières commencent par (?<=
pour les assertions positives, et (?<! pour les
assertions négatives. Par exemple :
(?<!foo)bar
trouve les occurrences de "bar" qui ne sont pas
précédées par "foo". Une assertion arrière peut
correspondre à des chaînes de longueur variable, jusqu'à une longueur
maximale définie par l'implémentation. Les alternatives de longueurs
différentes, telles que
(?<!dogs?|cats?)
et les alternatives au niveau supérieur pouvant correspondre à plus d'une
longueur, telles que
(?<=ab(c|de))
sont autorisées.
L'implémentation des assertions arrière déplace
temporairement le pointeur de position vers l'arrière, et cherche
à vérifier l'assertion. Si le nombre de caractères
est différent, la position ne sera pas correcte, et l'assertion
échouera. La combinaison d'assertions arrière avec des
sous-masques peut être particulièrement pratique à
fin des chaînes. Un exemple est donné à la fin de
cette section.
Avant PHP 8.4.0, qui intègre PCRE2 10.44, le contenu d'une assertion
arrière était limité de telle façon que les chaînes correspondantes
devaient toujours avoir une longueur fixe. Si plusieurs alternatives
étaient présentes, elles n'avaient pas besoin d'être de la même taille.
Ainsi,
(?<=bullock|donkey)
était autorisé, mais
(?<!dogs?|cats?)
provoquait une erreur de compilation. Les alternatives de longueurs
différentes n'étaient autorisées qu'au niveau supérieur des assertions
arrière. C'était une amélioration par rapport à Perl 5.005, qui imposait
à toutes les alternatives d'avoir la même taille. Une assertion telle que
(?<=ab(c|de))
n'était pas autorisée, car son unique alternative au niveau supérieur
pouvait correspondre à deux longueurs différentes. Pour la rendre
acceptable, il fallait l'écrire avec deux alternatives au niveau
supérieur :
(?<=abc|abde)
Plusieurs assertions peuvent intervenir successivement. Par exemple,
le masque
(?<=\d{3})(?<!999)foo
recherche les chaînes "foo" précédées
par trois chiffres qui ne sont pas "999". À noter que chaque assertion
est appliquée indépendamment, au même point de
la chaîne à traiter. Tout d'abord, il est
vérifié que les trois premiers caractères ont
tous des chiffres, puis on s'assure que ces trois caractères
ne sont pas "999". Le masque précédant
n'accepte pas "foo" précédé de
6 caractères, les trois premiers étant des chiffres et
les trois suivants étant différents de "999".
Par exemple, ce masque n'acceptera pas la chaîne
"123abcfoo". Pour ce faire, il faut utiliser le masque
suivant :
(?<=\d{3}...)(?<!999)foo.
Dans ce masque, la première assertion vérifie les six premiers
caractères, s'assure que les trois premiers sont des chiffres,
et la deuxième assertion s'assure que les trois derniers
caractères ne sont pas "999".
De plus, les assertions peuvent être imbriquées :
(?<=(?<!foo)bar)baz
recherche les occurrences de "baz" qui sont
précédées par "bar", qui,
à son tour, n'est pas précédé par
"foo". Au contraire,
(?<=\d{3}...(?<!999))foo
est un autre masque, qui recherche les caractères "foo",
précédés par trois chiffres, suivis de trois
autres caractères qui ne forment pas "999".
Les assertions ne sont pas capturantes, et ne peuvent pas être répétées. Si une assertion contient des sous-masques capturants en son sein, ils seront compris dans le nombre de sous-masques capturants du masque entier. La capture est réalisée pour les assertions positives, mais cela n'a pas de sens pour les assertions négatives.
200 assertions au maximum sont autorisées.