Services webmasters
Partenaires
Jeux concours gratuits
 
Assertions
<<<
Sous-masques uniques Les sous-masques conditionnels
>>>

7.89.9.1 Détails sur les expressions régulières
7.89.9 syntaxe des masques
7.89 Expressions régulières compatibles Perl
7 Index des fonctions
 Manuel PHP

Introduction
Méta-caractères
Antislash
Accent circonflexe et Dollar
Point
Crochets
Barre verticale
Options internes
Sous-masques
Répétitions
Références arrières
Assertions
->Sous-masques uniques
Les sous-masques conditionnels
Commentaires
Masques récursifs
Performances

Sous-masques uniques

Avec les quantificateurs de répétitions, l'échec d'une recherche conduit normalement à une autre recherche, avec un nombre différent de répétitions, pour voir si le masque ne s'applique pas dans d'autres conditions. Parfois, il est pratique d'éviter ce comportement, soit pour changer la nature de la recherche, soit pour la faire abandonner plus tôt, si on pense qu'il n'est pas besoin d'aller plus loin.

Considérons par exemple, le masque \d+foo appliqué à la ligne 123456bar . Après avoir tenté d'utiliser les 6 chiffres suivi de " foo " qui font échouer, l'action habituelle sera de réessayer avec 5 chiffres, puis avec 4, et ainsi de suite jusqu'à l'échec final.

Un sous-masque évalué une seule fois permettrait d'indiquer que lorsqu'une partie du masque est trouvée, elle n'a pas besoin d'être réévaluée à chaque tentative. Ceci conduirait à ce que la recherche échoue immédiatement après le premier test. Ces assertions ont leur propre notation, commençant avec (?> comme ceci : (?>\d+)bar .

Ce type de parenthèses verrouille le sous-masque qu'il contient un fois qu'il a été trouvé, et empêche un échec ultérieur d'y repasser, mais autorise à revenir plus loin en arrière. Une autre description est que les sous-masques de ce type recherche les chaînes de caractères, et les ancre le sous-masque à l'intérieur de la chaîne.

Les sous-masques uniques ne sont pas capturants. Des cas simples comme ceux présentés ci-dessus peuvent être pris comme des situations maximisantes, qui réservent le maximum de caractères. En effet, alors que \d+ et \d+? ajustent le nombre de chiffres trouvés de manière à laisser la possibilité au masque de réussir, (?>\d+) ne peut retenir que la séquence entière de chiffres. Cette construction peut contenir un nombre arbitraire de sous-masques complexes, et ils peuvent être imbriqués.

Les sous-masques uniques ne peuvent être utilisés qu'avec les assertions arrières, pour effectuer une recherche efficace en fin de chaîne. Considérons un masque simple tel que " abcd$ " appliqué à une très longue chaîne qui ne lui correspond pas. A cause du système de recherche de gauche à droite, PCRE va commencer par rechercher un " a " dans la chaîne sujet, puis vérifier si ce qui suit convient au reste du masque. Si le masque est spécifié sous la forme ^.*abcd$ alors, la séquence .* remplace en premier lieu la chaîne entière, et échoue, repart en arrière, et remplace tous les caractères sauf le dernier, échoue, retourne en arrière, prend un caractère de moins, etc... et ainsi de suite. Encore une fois, la recherche du " a " passe en revue toute la chaîne de gauche à droite, ce qui n'est pas très efficace. Par contre, si le masque était écrit ^(?>.*)(?<=abcd) alors il n'y aurait pas de retour en arrière, pour satisfaire la séquence .* , car elle ne peut que remplacer toute la chaîne. L'assertion arrière consécutive va alors faire un test sur les 4 derniers caractères. Si elle échoue, la recherche est immédiatement interrompue.

Pour les chaînes très longues, cette approche fait la différence en terme de performances et de temps de recherche. Lorsqu'un masque contient une répétition illimitée dans un sous-masque, qui contient lui-même un nombre illimité de répétiteur, l'utilisation des sous-masques à utilisation unique sont la seule façon d'éviter l'échec de la recherche à après un temps de calcul trop long.

Le masque (\D+|<\d+>)*[!?] recherche un nombre illimité de sous-chaînes, qui contiennent soit des non-chiffres, soit des chiffres inclus dans <>, suivi soit par ! ou par ? . Lorsqu'il trouve une solution, ce masque va très vite. Mais, lorsqu'il est appliqué à une chaîne telle que : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa , il lui faut beaucoup de temps pour annoncer un échec. Cela est dû au fait que la chaine peut être divisée en deux sous-chaînes d'un grand nombre de façons, et qu'elles ont toutes été essayées. (Cet exemple utilisait [!?] plutôt qu'un caractère simple, car PCRE et PHP utilise une optimisation qui leur permettent de détecter rapidement l'échec lorsqu'un caractère unique est trouvé. Il se souvient du dernier caractère qui est attendu, et s'aperçoit rapidement qu'il n'y a pas ce caractère).

Si le masque utilisé est ((?>\D+)|<\d+>)*[!?] les séquences de chiffres ne peuvent pas être trouvées, et l'échec intervient rapidement.

<< Sous-masques uniques >>
Assertions Détails sur les expressions régulières Les sous-masques conditionnels
Services webmasters
Les manuels
 
CoursPHP.com - Reproduction interdite -