Manuel PHP

Précédent

 

Suivant

Syntaxe des masques

Syntaxe des masques ñ Fonctionnement des expressions régulières

Description

La bibliothèque PCRE est un ensemble de fonction qui implémentent la recherche par expressions régulières, en utilisant la même syntaxe et la même sémantique que le Perl 5, avec quelques nuances (voir ci-dessous). Líimplémentation actuelle est celle de Perl .005.

Différences avec Perl

Les différences avec le Perl 5.005 sont présentée ici :

  1. Par défaut, un caractère díespacement correspond à níimporte quel caractère que la fonction C isspace() reconnaît, bien quíil soit possible de recompiler la bibliothèque PCRE avec díautres tables de caractère. Normalement, isspace() retourne true pour les espaces, les retours chariot, les nouvelles lignes, les formfeed, les tabulations verticales et horizontales. Le Perl 5 níaccepte plus la tabulation verticale comme caractère díespacement. La séquence \v qui était dans la documentation Perl depuis longtemps nía jamais été reconnue. Cependant, la tabulation verticale elle-même était reconnue comme un caractère díespacement jusquíà la version 5.002. Avec les version 5.004 et 5.005, líoption \s líignore.
  2. PRC ne tolère pas la répétition de quantificateurs dans les expressions. Perl le permet, mais cela ne signifie pas ce que vous pourriez penser. Par exemple, (?!a){3} ne síinterprète pas : les trois caractères suivants ne sont pas des "a". En fait, cela síinterprète comme : le caractère suivant níest pas "a" trois fois.
  3. Les occurrences de sous-masques qui interviennent dans des assertions négatives sont comptées, mais elles ne sont pas enregistrées dans le vecteur díoccurrences. Perl modifie ses variables numériques pour toutes les occurrences de sous masque, avant que líassertion ne vérifie le masque entier, et uniquement si les sous masques ne trouvent quíune seule occurrence.
  4. Bien que les caractères nul soient tolérés dans la chaîne de recherche, ils ne sont pas acceptés dans le masque, car le masque est utilisé comme une chaîne C standard, terminée par le caractère nul. Il faut donc utiliser la séquence díéchappement "\0" dans le masque pour rechercher les caractères nul.
  5. Les séquence díéchappement suivantes ne sont pas supportées par le Perl: \l, \u, \L, \U, \E, \Q. En fait, elles sont implémentées par la gestion intrinsèque de chaînes du Perl, et ne font pas partie de ses caractères spéciaux.
  6. Líassertion \G du Perl níest pas supportée car elle níest pas pertinente pour faire des recherches avec des masques uniques.
  7. De manière assez évidente, . PCRE níaccepte pas la construction (?{code})
  8. Au moment de líécriture de PCRE, Perl 5.005_02 avait quelques comportement étranges avec la capture des chaînes lorsquíune partie du masque est redoublée. Par exemple, "aba" avec le masque /^(a(b)?)+$/ va affecter à $2 la valeur "b", mais la même manipulation avec "aabbaa" et /^(aa(bb)?)+$/ laissera $2 vide. Cependant, si le masque est remplacé par /^(aa(b(b))?)+$/ alors $2 (et díailleurs $3) seront correctement affecté.
    Avec le Perl 5.004, $2 sera correctement affecté dans les deux cas, et cíest aussi vrai avec PCRE. Si Perl évolue vers un autre comportement cohérent, PCRE síadaptera probablement
  9. Une autre différence encore non résolue est le fait queíen Perl 5.005_02 le masque /^(a)?(?(1)a|b)+$/ accepte la chaîne "a", tandis que PCRE ne líaccepte pas. Cependant, que ce soit avec Perl ou PCRE /^(a)?a/ et "a" laisseront $1 vide.
  10. PCRE propose quelques extensions aux expressions régulières du Perl.
    (a) Bien que les assertions avec retour (lookbehind) soit obligée díapparier une chaîne de longueur fixe, toutes les assertions avec retour peuvent avoir une longueur différente. Perl 5.005 leur impose díavoir toutes la même longueur.
    (b) Si PCRE_DOLLAR_ENDONLY est mis, et que PCRE_MULTILINE níest pas mis , le méta caractère $ ne síapplique quíà la fin physqiue de la chaîne, et non pas avant les caractères de nouvelle ligne.
    (c) Si PCRE_EXTRA est mis, un backslash suivi díune lettre sans signification spéciale est considérée comme une erreur. followed by a letter
    (d) SI PCRE_UNGREEDY est mis, la "gourmandise" des quantificateurs de répétitions est inversées, ce qui est rend non gourmand par défaut, mais si ils sont suivis de ?, il seront gourmands.

Détails sur les expressions régulières

La syntaxe et la sémantique des expressions régulière supportées par PCRE sont décrites ci-dessous. Les expressions régulières sont aussi décrites dans la documentation Perl, et dans un grand nombre díautres livres, avec de nombreux exemples. Jeffrey Friedl's "Mastering Regular Expressions", édité chez O'Reilly (ISBN 1-56592-257-3), les décrits en profondeur. Cette description est organisée comme une documentation de référence.

Une expression régulière est un masque, qui est appliqué sur une chaîne sujet, de gauche à droite. La plus part des caractères se représentent eux-mêmes. Un exemple trivial : un masque qui serait

Le rapide renard gris

Pourra correspondre à une partie de la chaîne sujet qui sera identique au masque. La puissance des expressions régulières provient de leur capacité à autoriser des alternatives et des quantificateur de répétitions dans le masque. Ils sont encodés dans le masque par des méta caractères, qui ne représentent pas ce quíils sont, mais sont interprétés díune certaine manière.

Il y a deux sortes de méta caractères : ceux qui sont reconnus níimporte où dans un masque, hormis entre crochets, et ce qui sont reconnu entre crochets. A líextérieur des crochets, les méta caractères sont :

\ Caractère díéchappement, avec de multiples usages.

^ Le début de la chaîne sujet (ou de ligne, en mode multiligne)
$ La fin de la chaîne sujet (ou de ligne, en mode multiligne)
. Remplace níimporte quel caractère, hormis le caractère de nouvelle ligne (par défaut) ;

[ Caractère de début de définition de classe

] Caractère de fin de définition de classe

| Caractère de début díalternative
( Caractère de début de sous masque

) Caractère de fin de sous masque
? Etend le sens de (
mais aussi quantificateur de 0 ou 1
mais aussi quantificateur de minimisation
* Quantificateur de 0 ou plus
+ Quantificateur de 1 ou plus
{ Caractère de début de quantificateur minimum/maximum

La partie du masque qui est entourée de crochet et appelé une classe de caractères. Dans les classes de caractères, les seul méta caractères autorisés sont

\ Caractère díéchappement, avec de multiples usages
^ négation de la classe, mais uniquement si placé tout au début de la classe
- indique un intervalle de caractères
] termine la classe de caractères


La section suivante décrit líutilisation de chaque méta caractères :

BACKSLASH (\)
Le caractère backslash a de nombreuses utilisations. En premier lieu, si il est suivi díun caractère non alpha numérique, il ne prendra pas la signification spéciale qui y est rattachée. Cette utilisation du backslash comme caractère díéchappement síapplique à líintérieur et à líextérieur des classes de caractères.


Par exemple, pour recherche le caractère étoile "*", il faut écrire dans le masque : "\*". Cela síapplique dans tous les cas, que le caractère qui suive soit un méta caractère ou non. Cíest un moyen sur pour síassurer quíun caractère sera recherché pour sa valeur litérale, plutot que pour sa valeur spéciale. En particulier, pour rechercher les backslash, il faut écrire : "\\".

Si un masque est utilisé avec líoption PCRE_EXTENDED, les espaces blancs du masque, mais qui ne sont pas dans une classe de caractère, et les caractères entre dièses "#", ainsi que les nouvelles lignes sont ignorées. Le backslash peut être utilisé pour échapper et ainsi rechercher un espace ou un dièse.

La deuxième utilité du backslash est de pouvoir coder des caractères invisibles dans les masques. Il níy a pas de restriction sur la place de ces caractères invisibles, hormis pour le caractère nul qui doit terminer le masque. Lors de la préparation du masque, il est souvent plus pratique díutiliser les séquences díéchappement suivantes, plutôt que le caractère binaire quíelle représente :


\a alarme, cíest à dire le caractère BEL (hex 07)
\cx "control-x", avec x qui peut être níimporte quel caractère.

\e escape (hex 1B)
\f formfeed (hex 0C)
\n nouvelle ligne (hex 0A)
\r retour chariot (hex 0D)
\t tabulation (hex 09)
\xhh caractère en hexadécimal, de code hh
\ddd caractère en octal, de code ddd, ou référence arrière

Dans la séquence "\cx" si "x" est en minuscule, il est converti en majuscule. Puis, le bit 6 (hex 40) est inversé. Ainsi "\cz" devient 1A, mais "\c{" devient hex 3B, tandis que "\c;" devient hex 7B.

Après "\x", deux caractères hexadécimal sont lus (les lettres peuvent être en majuscule ou minuscule).


Après "\0", deux caractères octal sont lus. Dans chacun des cas, le méta caractère tente de lire autant de caractère que possible. Ainsi la séquence "\0\x\07", sera comprise comme deux caractères nuls, suivi díun caractère alarme (BEL). Assurez vous que vous fournissez suffisamment de chiffres après le métacaractère.


La gestion de la séquence "\y", avec y <> 0 est plutot compliquée. En dehors des caractères de classes, PCRE va lire y et tous les caractères qui suivent comme des chiffres décimaux. Si y est plus petit que 10, ou bien si il y a déjà eu au moins autant de parenthèses ouvrantes auparavant, la séquence est prise pour une référence de retour. Le détail sera vu ultérieurement, après la section sur les sous-masques.


A líintérieur díun caractère de classe, ou si y est plus grand que 10, et quíil níy a pas eu assez de parenthèses ouvrantes auparavant, PCRE lis jusquíà 3 chiffres octals à la suite du backslash, et génére un octet unique, à partir des 8 bits de poids faible de la séquence. Tous les chiffres qui suivent ne sont pas interprétés, et se representent eux-mêmes. Par exemple,

\040 est une autre manière díécrire un espace, et \40 est identique, dans la mesure où il níy a pas 40 parenthèses ouvrantes auparavant.
\7 est toujours une référence de retour.
\11 peut être une référence de retour, ou une tabulation, tandis que \011 est toujours une tabulation
\0113 est une tabulation suivi du caractère "3", tandis que \113 est le caractère 113 (étant donné quíil ne peut y avoir plus de 99 référence de retour)
\377 est un octet dont tous les bits sont à 1
\81 peut être soit une référence de retour, soit le caractère nul, suivi des caractères "8" et "1"

Les valeurs octales supérieures ou égales à 100 ne doivent pas être introduite par un 0, car seuls les trois premiers octets seront lus.

Toutes les séquences qui définissent une valeur díun seul octet peuvent être utilisé dans les classes de caractères, et à líextérieur. De plus, dans une classe de caractère, la séquence "\b" est interprétée comme un caractère effacer (backspace, hex 08). A líextérieur díune classe de caractères, il peut avoir díautres significations (voir ci-dessous)

On peut encore se servir de backslash pour préciser des types génériques de valeurs :

\d tout caractère décimal
\D tout caractère qui níest pas un caractère décimal
\s tout caractère blanc
\S tout caractère qui níest pas un caractère blanc
\w tout caractère de "mot"
\W tout caractère qui níest pas un caractère de "mot"

Chaque paire précédente définit une partition de la table des caractères : les deux ensembles sont disjoints. Un caractère satisfera soit un méta caractère, soit líautre.


Un caractère de "mot" sera une lettre, un chiffre ou le caractère souligné, cíest à dire un caractère qui pourra être une partie díun mot Perl. La définition des lettres et chiffres est définie par les tables de caractères de PCRE, et peut varier suivant la table locale de caractère (voir "Tables de caractères locales ", ci-dessus. Par exemple, dans la configuration français ("fr"), certains caractères ont des codes supérieurs à 128, pour les caractères accentués, et ils seront compris par le méta caractère \w.

Ces séquences de caractères peuvent apparaître à líintérieur ou à líextérieur des classes de caractères. Elles remplacent à chaque fois un caractère du type correspondant. Si cette séquence est mis en fin de masque, et quíil níy a plus de caractère à comparer dans la chaîne sujet, la recherche échoue.

La quatrième utilisation du backslash intervient lors díassertions simples. Une assertion impose une condition à un certain point, sans remplacer de caractère. Líutilisation de sous-masques pour réaliser des assertions plus complexes est décrites plus bas. Les assertions avec backslash sont les suivantes :

\b limite de mot
\B pas de limite de mot
\A début de la chaîne sujet (indépendant du mode multi-lignes)
\Z fin de la chaîne sujet ou nouvelle ligne à la fin de la chaîne sujet (indépendant du mode multi-lignes)
\z fin de la chaîne sujet (indépendant du mode multi-lignes)

Ces assertions ne peuvent pas apparaître dans une classe de caractère (mais "\b" a une autre signification à líintérieur díune classe de caractères)
Une limite de mot est un emplacement dans la chaîne sujet ou un caractère et son suivant ne sont pas en même temps des caractères de mot, ou le contraire (on peut le voir comme \w\W ou \W\w), ou encore le premier ou le dernier caractère est un caractère mot.


Les assertions \A, \Z, et \z diffèrent des méta caractères ^et $ dans la mesure où ils ne sont pas dépendants des options, notamment PCRE_NOTBOL ou PCRE_NOTEOL. La différence entre \Z et \z tient au fait que \Z recherche les positions avant les nouvelles lignes et à la fin de la chaîne sujet, tandis que \z ne recherche que la fin de la chaîne.


Accent circonflexe et dollar
En dehors díune classe de caractère, avec les options par défaut,

^ est une assertion qui níest vraie que si elle est placée tout au début de la chaîne. A líintérieur díune classe de caractère, ^a un tout autre sens (voir ci-dessous).

^ nía pas besoin díêtre le premier caractère du masque, si plusieurs alternatives sont proposées, mais il doit être placé en premier dans chaque alternative. Si toutes les alternatives commencent par ^, alors le masque est dit ancré (il y a une autre construction qui porte cette appellation).


$ est une assertion qui níest vraie que si elle est placée tout en fin de chaîne ou juste avant un caractère de nouvelle ligne qui serait le dernier caractère de la chaîne. A líintérieur díune classe de caractère, ^a un tout autre sens (voir ci-dessous).

$ nía pas besoin díêtre le dernier caractère du masque, si plusieurs alternatives sont proposées, mais il doit être placé en dernier dans chaque alternative. Si toutes les alternatives finissent par $, alors le masque est dit ancré (il y a une autre construction qui porte cette appellation). $ nía pas de valeur particulière dans une classe de caractères.


La signification de $ peut changer, de manière à líamener à ce quíil ne puisse se trouver quíen toute fin de la chaîne sujet. Cela se fait en ajoutant líoption PCRE_DOLLAR_ENDONLY au moment de la compilation, ou de líexécution. Cette option est inopérante sur \Z.

La signification de ^ peut changer, de manière à líamener à ce quíil puisse se trouver immédiatement avant et immédiatement après un caractère de nouvelle ligne "\n". Cela se fait en ajoutant líoption PCRE_MULTILINE au moment de la compilation, ou de líexécution. Par exemple, le masque /^abc$/ accepte la chaîne
"def\nabc" uniquement en mode multi ligne. Par conséquent, toutes les parties du masques qui commencent par "^" ne sont pas ancrées, en mode multi ligne. Líoption PCRE_DOLLAR_ENDONLY est ignorée si líoption PCRE_MULTILINE est choisie.


Notez que les méta caractères \A, \Z, et \z peuvent servir à reperer le débu et la fin du sujet, et toutes les parties du masque qui commenceront par \A seront toujours ancrées, avec líoptoin PCRE_MULTILINE ou non.


Point
En dehors díune classe de caractères, un point remplace níimporte quel caractère, même invisible et à líexception du caractère de nouvelle ligne. Avec líoption PCRE_DOTALL le point remplace níimporte quel caractère, même le caractère de nouvelle ligne. La gestion des points et complètement indépendante de ^et $. Le seul point commun est que les deux ont un comportement particulier vis à vis des caractère de nouvelle ligne. Le point nía pas de comportement particulier dans une classe de caractères.


Crochets [ ]
Un crochet ouvrant introduit une classe de caractère, et le crochet fermant la conclu. Le crochet fermant nía pas de signification en lui même. Si le crochet fermant est nécessaire à líintérieur díune classe de caractères, il faut quíil soit le premier caractère (après un ^ éventuel) ou échappé avec un backslash.


Une classe de caractère remplace un seul caractère dans la chaîne sujet, à moins que le premier caractère de la classe soit un ^, qui représente une négation : le caractère ne doit pas se trouver dans la classe. Si ^ est nécessaire dans la classe, il suffit quíil ne soit pas le premier caractère, ou bien quíil soit échappé avec un backslash.

Par exemple, le caractère [aeiou] remplace níimporte quelle voyelle minuscule, tandis que [^aeiou] remplace níimporte quelle caractère qui níest pas une voyelle minuscule. ^ est une notation pratique pour spécifier des caractères qui sont dans une classe, en ne citant que ceux qui níy sont pas. Le comportement est inchangé.
Avec líoption díinsensibilité à la casse, toutes les lettres díune classe de caractère représentent en même temps la majuscule et la minuscule. Par exemple, [aeiou] représentera "A" ou "a", et [^aeiou] níacceptera pas "A", tandis que sans líoption, elle líaccepterait.


Le caractère de nouvelle ligne níest pas traité de manière spéciale dans les classes de caractère, quelque soit líoption PCRE_DOTALL ou PCRE_MULTILINE. Une classe telle que [^a] acceptera toujours une nouvelle ligne.

Le signe moins (-) est utilisé pour spécifier un intervalle de caractères, dans une classe. Par exemple, [d-m] remplace toutes les lettres entre d et m inclus. Si le caractère moins est requis dans une classe, il faut líéchapper avec un backslash, ou le faire apparaître à une position ou il ne pourra pas être interprété comme une indication díintervalle, cíest à dire au début ou à la fin de la classe.
Il níest pas possible díavoir le caractère "]" comme fin díintervalle. Un masque tel que [W-]46] est compris comme la classe de caractère contenant deux caractères ("W" et "-") suivi de la chaîne littérale "46]", ce qui fait quíil va accepter "W46]" ou "-46]". Cependant, si "]" est échappé avec un backslash, le masque [W-\]46] est interprété comme une classe díun seul caractère, contenant un intervalle de caractère. La valeur octale ou hexadécimale de "]" peuvent aussi être utilisée pour déterminer les limites de líintervalle.


Les intervalles travaillent sur des séquences ASCII. Elles peuvent aussi être précisées avec des valeurs numériques, par exemple [\000-\037]. Si cet intervalle inclus des lettres utilisées avec une option díinsensibilité de casse, les majuscules ou minuscules correspondantes seront aussi incluses. Par exemple, [W-c] est équivalent é [][\^_`wxyzabc], avec líoption díinsensibilité de casse. Si la table locale de caractère est "fr", [\xc8-\xcb] correspond aux caractères accentués.

Les types de caractères \d, \D, \s, \S, \w, et \W peuvent aussi intervenir dans les classes de caractères. Par exemple, [\dABCDEF] acceptera níimporte quel caractère hexadécimal. Un accent circonflexe peut aussi être utilisé pour spécifier adroitement des ensembles de caractères plus restrictifs : par exemple [^\W_] accepte toutes les lettres et les chiffres, mais pas les soulignés.


Tous les caractères non alphanumériques autres que \, -, ^ (placé en début de chaîne)et ] níont pas de significations particulière, mais ils ne perdront rien à être échappés.

Barre verticale |
La barre verticale sert à séparer des alternatives. Par exemple, dans le masque

dupont|martin

recherche soit "dupont", soit " martin ". Le nombre díalternative níest pas limité, et il est même possible díutiliser la chaîne vide. Lors de la recherche, toutes les alternatives sont essayées, de gauche à droit, et la première qui est acceptée, est utilisée. Si les alternatives sont dans un sous masque, elle ne réussiront que si le masque principal réussi aussi.




Options mises dans le masque
Les options PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, et PCRE_EXTENDED peuvent être changée depuis le masque lui-même, avec des séquences mises "(?" et ")". Les options sont

i pour PCRE_CASELESS
m pour PCRE_MULTILINE
s pour PCRE_DOTALL
x pour PCRE_EXTENDED

Par exemple, (?im) rend le masque insensible à la casse, et multi lignes. Il est possible díannuler ces options en les faisant précéder par un signe - : Par exemple (?im-sx), ajoutera les options PCRE_CASELESS et PCRE_MULTILINE mais annulera les options PCRE_DOTALL et PCRE_EXTENDED. Si une option apparaît avant et après le signe moins, líoption sera annulée.


Le domaine díapplication de ces options dépend de la position de la séquence díoption. Pour toutes les séquences díoptions qui sont hors des sous masques (définis plus loin), líeffet est le même que si líoption avait été fixée dès le début de la recherche. Les exemples suivants se comportent tous de la même façons :
(?i)abc
a(?i)bc
ab(?i)c
abc(?i)

et sont parfaitement équivalent au masque abc avec líoption PCRE_CASELESS. En díautres termes, mettre des séquences díoptions dans le corps principal du masque revient à appliquer líoption à tout le masque, sauf ordre contraire dans les sous masques. Si il y a plusieurs séquences díoption qui portent sur la même optin, la dernière síappliquera.

Si une option intervient dans un sous-masque, le comportement est différent. Cíest un changement de comportement apparu en Perl 5.005. Une option à líintérieur díun sous masque níaffecte que cette partie du masque, ce qui fait que

(a(?i)b)c

acceptera abc et aBc mais aucune autre chaîne (en supposant que PCRE_CASELESS níest pas utilisé). Cela signifie que les options permettent díavoir différente configuration de recherche pour différentes parties du masque. Une séquence díoption dans une alternative affecte toute líalternative. Par exemple :

(a(?i)b|c)

accepte "ab", "aB", "c", et "C", même si, comme dans le cas de "C", la première alternative qui porte líoption níest pas prise en compte. Sinon, cela risque díintroduire des comportements très étranges :

Les options spécifiques à PCRE telles que PCRE_UNGREEDY et PCRE_EXTRA peuvent être modifiées de la même manière, en utilisant respectivement les caractères U et X. Líoption (?X) est particulière, car elle doit toujours intervenir avant toutes les autres options, même au niveau du masque entier. Il vaut mieux la mettre au début du masque.


Sous masques

Les sous masques sont délimités par des parenthèses, et peuvent être imbriquées. Ajouter des sous masques a deux utilités :

1. Délimiter des alternatives. Par exemple, le masque

char(don|mant|)

acceptera les mots "char", "chardon", ou "charmant". Sans les parenthèses, il níaccepterait que "chardon",
"mant" ou la chaîne vide.


2. Le sous masque est considéré comme capturante : Lorsquíune chaîne sujet est acceptée par le masque complet, les sous masques sont transmis à líappelant grâce à un vecteur de sous masques. Les parenthèses ouvrantes sont comptées de gauche à droite, (commencant à 1).


Par exemple, soit la chaîne sujet "le roi soleil " qui est utilisée avec le masque suivant :


Le ((roi|prince) (soleil|charmant))

les sous masques capturé sont "roi soleil ", "roi", et "soleil", numéroté respectivement 1, 2, et 3.

Le ubiquité des parenthèses níest pas toujours simple díemploi. Il y a des moments où regrouper des sous masques est nécessaire, sans pour autant captuer la valeur trouvée. Si une parenthèse ouvrante est suivie de "?:", le sous masque ne capture pas la chaîne assortie, et ne sera pas compté lors de la numérotation des captures. Par exemple, avec la chaîne "le prince charmant", utilisé avec le masque
pattern

Le (( ?roi|prince) (soleil|charmant))

les chaînes capturées seront "prince charmant " et "charmant", numéroté respectivement 1 et 2. Le nombre maximal de chaîne capturées est de 99, et le nombre total de sous masque (capturant ou non) ne doit pas dépasser 200.


Les séquences díoptions disposent ici díun raccourci pratique : si un sous masque non capturant a besoin de séquence díoption particulières, il suffit díajouter ces options après entre "?"et deux points ":". Les deux écritures suivantes sont identiques :

(?i:samedi|dimanche)
(?:(?i) samedi | dimanche)

. De plus, comme les séquences díoptions sont valables sur toute une alternative, le masque ci dessus acceptera aussi "DIMANCHE" que "Dimanche".



Répétition
les Répétitions sont spécifiées avec des quantificateurs, qui peuvent être placés à la suite des caractères suivants :


Un caractère unique, même síil síagit díun méta caractère
Une classe de caractères
Une référence de retour (Voir section suivante)
Un sous masque avec parenthèses (a moins que ce ne soit une assertion, voir plus loin)


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 petit 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étition 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 exactements. Une accolade ouvrante qui apparaît à une position où un quantificateur níest pas accepté, ou si la syntaxe des quantificateurs níest pas respectée, elle sera considérée littérale. Par exemple, {,6} níest pas un quantificateur, mais une chaîne de 4 caractères.


Le quantificateur {0} est autorisé, mais líexpression est alors ignorée.


Pour des raisons pratiques et historiques, les trois quantificateurs les plus courants ont des abréviations sous la forme díun méta 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. Cependant, si la répétion du sous masque ne trouve aucun caractère, la boulce est interrompue.

Par défaut, les quantificateurs sont "gourmands", cíest à dire, quíils cherchent díabord à trouve le nombre maximal de répétitions qui autorise le succès de la recherche. Líexemple classique posé par cette gourmandise est la recherche de commentaire díun programme en C. Les commentaires apparaissent entre les séquences /* et */ et à líintérieur de ces délimiteurs, les* et / sont autorisés. Appliquer le masque

/\*.*\*/

à la chaîne

/* premier commentaire */ commande /* second commentaire */

ne peut réussire, 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. A cause cette ambiguité, 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 mise, (une option qui níest pas disponible avec Perl) alors les quantificateurs sont non gourmand par défaut, mais peuvent être rendu gourmand au cas par cas, en ajoutant un point díinterrogation après. En díautres termes, cette option inverse le comportement par défaut.


Lorsquíun sous masque est quantifié avec un nombre minimum de répétition, qui soit plus grand que 1, ou avec un maximum de répétition, 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 mise, cíest à dire en autorisant le remplacement des nouvelles lignes par un méta caractè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éta caractère \A. Dans le cas où on sait díavance quíil níy aura pas de caractère de nouvelle ligne, mettre líoption PCRE_DOTALL et commencer le masque par.* permet díoptmiser 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*)+

ai été appliqué à "internet interne" la valeur de la chaîne capturée est "interne". Cependant, si 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".



Références arrières (back reference)s

En dehors des classes de caractères, un backslash suivi díun nombre plus grand que 0 (et possiblement plusieurs chiffres) est une référence arrière (cíest à dire vers la gauche) dans le masque, en supposant quíil y ait suffisamment de sous masques capturant précédent.


Cependant, si le nombre décimal suivant le backslash est plus petit que 10, il sera toujours considéré comme une référence arrière, et cela générera une erreur si le nombre de capture níest pas suffisant. En díautres termes, il faut quíil existe suffisamment de parenthèses ouvrantes à gauche de la référence, surtout si la référence est inférieure à 10. Reportez vous à la section "Backslash" pour avoir de plus amples détails à propos du nombre de chiffres qui suivent le backslash.

La référence arrière remplace ce qui a été capturé par un sous masque dans le masque courant, plutôt que remplace le sous masque lui même. Ainsi

(calme|rapide) et \1ment

trouvera "calme et calmement " et "rapide et rapidement ", mais pas " calme et rapidement ". Si la recherche tiens compte de la casse, alors la casse de la chaîne capturée sera importante. Par exemple,

((?i)rah)\s+\1

trouve "rah rah" et "RAH RAH", mais pas "RAH rah", même si le sous masque capturant initial ne tenait pas compte de la casse.



Il peut y avoir plusieurs références arrières dans le même sous masque. Si un sous masque nía pas été utilisé dans une recherche, alors les références arrières échoueront : par exemple

(a|(bc))\2

ne réussira jamais si la chaîne sujet commence par "a" plutôt que par "bc".
Etant donné quíil peyt y avoir jusquíà 99 références arrières, tous les chiffres après le backslash sont considérés comment faisant potentiellement partie de la référence arrière. Si le masque recherche un chiffre après la référence, alors il faut impérativement utiliser des délimiteurs pour terminer la référence arrière. Si líoption PCRE_EXTENDED est mise, on peut utiliser un espace. Sinon, un commentaire vide fait líaffaire.


Une référence arrière qui intervient à líintérieur de parenthèses auquel elle fait référence échouera dès que le sous masque sera utilisé. Par exemple, (a\1) échouera toujours. Cependant, ces références peuvent être utiles dans les sous masques répétitifs. Par exemple, le masque

(a|b\1)+

pourra convenir pour "a", "aba", "ababaa" etc. A chaque itération du sous masque, la référence arrière utilise le résultat du dernier sous masque. Pour que cela fonctionne, il faut que la première itération níai pas besoin díutiliser la référence arrière. Cela arrive avec les alternatives, comme dans líexemple ci dessus, ou avec un quantificateur de minimum 0.


Les assertions

Une assertion est un test sur les caractères suivants ou précédent celui qui est en cours díétude. Ce test ne consomme par de caractère (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écrite précédemment. Il existe cependant un type díassertion plus complexe, codées sous la forme de sous masques. Il en existe deux types : ceux qui travaille au dela de la position courante, et ceux qui travaille en deça.

Une assertions 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 des assertions négatives. Par exemple :


\w+(?=;)

síassure quíun mot est suivi díun point virgule, mais níinclus pas le point virgule dans la capture. Díautre part,

foo(?!bar)

recherche toutes les occurrences de "foo" qui ne soit pas suivie de "bar". Le masque


(?!foo)bar

en est proche, mais ne trouve pas une occurrence de "bar" qui soit précédée par quelques chose díautre que "foo"; il trouve toutes les occurrences de "bar", quelque 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. Ces assertions 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". Le contenu díune référence arrière est limité de tel façon que les chaînes quíil utilise sont toujours de la même taille. Cependant, lorsquíil y a plusieurs alternatives, elles níont pas besoin díêtre de la même taille.


(?<=taureau|ane)

est autorisé, tandis que

(?<!chiens?|chats?)

provoque une erreur de compilation. Les alternatives qui ont des longueurs différentes ne sont autorisées quíau niveau supérieur des assertions arrières. Cíest une amélioration du fonctionnement de Perl 5.005, qui impose aux alternatives díavoir toutes la même taille. Une assertion telle que

(?<=ab(c|de))

níest pas autorisée, car líassertion de bas niveau (la deuxième, ici) a deux alternatives de longueurs différentes. Pour la rendre acceptable, il faut écrire

(?<=abc|abde)

Lí implémentation des assertions arrières déplace temporairement le pointeur de position vers líarrière, et cherche à vérifier líassertion. Si le nombre de caractère est différent, la position ne sera pas correcte, et líassertion échouera. La combinaison díassertions arrières avec des sous masques peut être particulièrement pratique à fin des chaînes. Un exemple est donné à la fin de cette section.


Plusieurs assertions peuvent intervenir successivement. Par exemple


(?<=\d{3})(?<!999)foo

recherche les chaînes "foo" précédée par trois chiffres qui 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".

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.


Sous masques uniques (ONCE-ONLY SUBPATTERNS)
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 fait é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, commencant 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 reservent le maximum de caractères. En effet, alors que \d+ et \d+? ajustent le nombre de chiffres trouvé 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 suejet, 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 performance et de temps de recherche.


Les sous masques conditionnels
Il est possible de lier un sous masque à un une condition, ou de choisir entre deux sous masques alternatifs, en fonction du résultat díune assertion, ou suivant les résultats de recherche précédents. Les deux formes possibles de sous masques conditionnels sont


(?(condition)masque positif)
(?(condition) masque positif | masque négatif)

Si les conditions sont satisfaites, le masque positif est utilisé, sinon, le masque négatif est utilisé, si présent. Si il y a plus de deux alternatives, une erreur est générée à la compilation.

Il y a deux types de conditions. Si le texte entre les parenthèses est une séquence de chiffre, alors la condition est satisfaite si le sous masque correspondant à ce numéro a réussi. Considérons le masque suivant, qui contient des espaces non significatif pour le rendre plus compréhensible (on supposera líoption PCRE_EXTENDED mise) et qui est divisé en trois parties pour simplifier les explications


( \( )? [^()]+ (?(1) \) )

La première partie recherche une parenthèse ouvrante optionnelle, et si elle existe, elle est capturée. La deuxième partie recherche un séquence de caractères qui ne contient pas de parenthèses. La troisième partie est conditionnée à la première, et síassure que si il y avait une parenthèse ouvrante, il en existe une fermante. Si une parenthèse ouvrante a été trouvée, elle a été capturée, et donc la première capture existe, et la condition est exécutée. Sinon, elle est ignorée. Ce masque recherche donc une séquence de lettre, éventuellement mis entre parenthèse.


Si la condition níest pas une séquence de nombre, il faut que ce soit une assertion. Ce peut être une assertion positive ou négative, arrière ou avant. Considérons le masque suivant (même conditions que le précédent) et avec deux alternatives en seconde ligne :

(?(?=[^a-z]*[a-z])
\d{2}[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} )

La condition est une assertion avant positive, qui recherche une séquence optionnelle de caractère non-lettre. En díautres termes, elle teste la presence díau moins une lettre dans la chaîne sujet. Si une lettre est trouvée, la recherche se poursuit avec la première alternative, et sinon, avec la seconde. Ce masque recherche des chaînes de la forme dd-aaa-dd ou dd-dd-dd, avec aaa qui sont des lettres, et dd qui sont des chiffres



Commentaires
La séquence (?# marque le début des commentaires, qui se termine à la prochaine parenthèse fermante. Les parenthèses imbriquées ne sont pas autorisées. Les caractères entre ces délimiteurs ne jouent alors aucun rôle dans le masque.

Si líoption PCRE_EXTENDED est mise, les caractères dièses # non échappés en dehors díune classe de caractères introduisent un commentaire qui continuera jusquíà la prochaine ligne dans le masque.


Performances
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 généralement 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 mise, le masque est implicitement ancré par PCRE, étant donné quíil ne peut que rechercher au début de la chaîne. Cependant, si option PCRE_DOTALL níest pas mise, PCRE ne peut faire aucune optimisation ca le méta caractères . 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 utiliser un tel masque avec des chaînes qui ne contiennent pas de caractères de nouvelles lignes, 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.

Précédent

Sommaire

Suivant

Pattern Options

Chapitre

PDF functions