Certaines séquences de recherches sont plus efficaces que d'autres.
Ainsi, il est plus efficace d'utiliser une classe de caractères
telle que [aeiou]
plutôt qu'une alternative
(a|e|i|o|u)
.
En général, le masque le plus simple, qui permette
la recherche désirée est le plus efficace. Le livre
de Jeffrey Friedl's contient de nombreuses études à
propos de l'optimisation des expressions régulières.
Lorsqu'un masque commence par.* et que l'option
PCRE_DOTALL est
activée, le masque est implicitement ancré par PCRE,
étant donné qu'il ne peut que rechercher au début
de la chaîne. Cependant, si l'option
PCRE_DOTALL n'est pas
activée, PCRE ne peut faire aucune optimisation, car le
métacaractère point ".
"
ne remplace pas une nouvelle ligne, et si la chaîne
sujet contient des nouvelles lignes, le masque peut trouver une
solution qui serait située juste après une
de ces nouvelles lignes, et non pas seulement au début
de la chaîne sujet. Par exemple, le masque,
(.*)second
acceptera la chaîne "premier \net second
"
(avec "\n
" qui remplace la nouvelle ligne),
et la première chaîne capturée sera "et
".
Afin d'effectuer la recherche, PCRE va essayer d'appliquer le masque
à partir de chaque début de ligne.
Si vous utilisez un tel masque avec des chaînes qui ne contiennent
pas de caractères de nouvelle ligne, les meilleures performances
seront atteintes avec l'option
PCRE_DOTALL, ou en ancrant le
masque avec ^.*
. Cela évite à PCRE
de scanner toute la chaîne pour rechercher un caractère
de nouvelle ligne et recommencer la recherche.
Attention aux masques qui contiennent des quantificateurs infinis
imbriqués. Ils peuvent demander un temps de calcul très
long, lorsque appliqués à une chaîne qui ne
correspond pas à ce masque. Par exemple,
(a+)*
Ce masque peut accepter "aaaa
" de 33 manières
différentes, et ce nombre croit rapidement avec la taille
de la chaîne (le quantificateur *
peut prendre
les valeurs de 0, 1, 2, 3, ou 4, et pour chaque cas non nul, le
quantificateur +
peut prendre différentes
valeurs). Lorsque le reste de la chaîne est tel que l'on s'achemine
vers un échec, PCRE doit en principe vérifier
toutes les possibilités, et cela prend un temps
extrêmement long.
Un optimiseur repère les cas les plus simples, tel que
(a+)*b
où un caractère simple suit les quantificateurs.
Avant de partir dans les procédures standards de recherche, PCRE
s'assure qu'il y a au moins un "b
" dans la
chaîne, et si ce n'est pas le cas, l'échec est
annoncé immédiatement. Sinon, il n'y a pas
d'optimisation dans la recherche. Vous pouvez voir la
différence de comportement avec le masque suivant :
(a+)*\d
.
Le premier retourne un échec quasi-immédiatement, s'il est appliqué à
une ligne de "a
", alors que le second masque
prend un temps significatif pour une chaîne de plus de
20 caractères.