.\" Automatically generated by Pod::Man 2.06 (Pod::Simple 3.04) .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' .\" expand to `' in nroff, nothing in troff, for use with C<>. .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "PERLRE 1" .TH PERLRE 1 "2006-03-03" "DocFr" "User Contributed Perl Documentation" .SH "NAME/NOM" .IX Header "NAME/NOM" perlre \- Les expressions rationnelles en Perl .SH "DESCRIPTION" .IX Header "DESCRIPTION" Cette page de\*'crit la syntaxe des expressions rationnelles en Perl. Dans \&\*(L"Ope\*'rateurs d'expression rationnelle\*(R" in perlop, vous trouverez une pre\*'sentation des ope\*'rateurs \f(CW\*(C`m//\*(C'\fR, \f(CW\*(C`s///\*(C'\fR, \f(CW\*(C`qr//\*(C'\fR et \f(CW\*(C`??\*(C'\fR avec une description de l'\fIusage\fR des expressions rationnelles dans des ope\*'rations de reconnaissances assortie de nombreux exemples. (NdT: on emploie couramment le terme \*(L"expression re\*'gulie\*`re\*(R" car le terme anglais est \*(L"regular expression\*(R" qui s'abre\*`ge en \*(L"regexp\*(R". Mais ne nous y trompons pas, en franc\*,ais, ce sont bien des \*(L"expressions rationnelles\*(R".) .PP Les ope\*'rations de reconnaissances peuvent utiliser diffe\*'rents modificateurs. Les modificateurs qui concernent l'interpre\*'tation des expressions rationnelles elles\-me\*^mes sont pre\*'sente\*'s ici. Pour les modificateurs qui modifient l'usage des expressions rationnelles fait par Perl, regarder \*(L"Ope\*'rateurs d'expression rationnelle\*(R" in perlop et \&\*(L"Les de\*'tails sordides de l'interpre\*'tation des chai\*^nes\*(R" in perlop. .IP "i" 4 .IX Item "i" Reconnaissance de motif inde\*'pendamment de la casse (majuscules/minuscules). .Sp Si \f(CW\*(C`use locale\*(C'\fR est actif, la table des majuscules/minuscules est celle du locale courant. Voir perllocale. .IP "m" 4 .IX Item "m" Permet de traiter les chai\*^nes multi\-lignes. Les caracte\*`res \*(L"^\*(R" et \*(L"$\*(R" reconnaissent alors n'importe quel de\*'but ou fin de ligne pluto\*^t qu'au de\*'but ou a\*` la fin de la chai\*^ne. .IP "s" 4 .IX Item "s" Permet de traiter une chai\*^ne comme une seule ligne. Le caracte\*`re \*(L".\*(R" reconnai\*^t alors n'importe quel caracte\*`re, me\*^me une fin de ligne qui normalement n'est pas reconnue. .Sp Les modificateurs \f(CW\*(C`/s\*(C'\fR et \f(CW\*(C`/m\*(C'\fR passent outre le re\*'glage de \f(CW$*\fR. C'est a\*` dire que, quel que soit le contenu de \f(CW$*\fR, \f(CW\*(C`/s\*(C'\fR sans \f(CW\*(C`/m\*(C'\fR obligent \*(L"^\*(R" a\*` reconnai\*^tre uniquement le de\*'but de la chai\*^ne et \*(L"$\*(R" a\*` reconnai\*^tre uniquement la fin de la chai\*^ne (ou juste avant le retour a\*` la ligne final). Combine\*'s, par /ms, ils permettent a\*` \*(L".\*(R" de reconnai\*^tre n'importe quel caracte\*`re tandis que \&\*(L"^\*(R" et \*(L"$\*(R" reconnaissent alors respectivement juste apre\*`s ou juste avant un retour a\*` la ligne dans la chai\*^ne. .IP "x" 4 .IX Item "x" Augmente la lisibilite\*' de vos motifs en autorisant les espaces et les commentaires. .PP Ils sont couramment nomme\*'s X le modificateur \f(CW\*(C`/X\*(C'\fR X, me\*^me si le de\*'limiteur en question n'est pas la barre oblique (\f(CW\*(C`/\*(C'\fR). En fait, tous ces modificateurs peuvent e\*^tre inclus a\*` l'inte\*'rieur de l'expression rationnelle elle\-me\*^me en utilisant la nouvelle construction \f(CW\*(C`(?...)\*(C'\fR. Voir plus bas. .PP Le modificateur \f(CW\*(C`/x\*(C'\fR lui\-me\*^me demande un peu plus d'explication. Il demande a\*` l'interpre\*'teur d'expressions rationnelles d'ignorer les espaces qui ne sont ni pre\*'ce\*'de\*'s d'une barre oblique inverse (\f(CW\*(C`\e\*(C'\fR) ni a\*` l'inte\*'rieur d'une classe de caracte\*`res. Vous pouvez l'utiliser pour de\*'couper votre expression rationnelle en parties (un peu) plus lisibles. Le caracte\*`re \f(CW\*(C`#\*(C'\fR est lui aussi traite\*' comme un me\*'ta\-caracte\*`re introduisant un commentaire exactement comme dans du code Perl ordinaire. Cela signifie que, si vous voulez de vrais espaces ou des \&\f(CW\*(C`#\*(C'\fR dans un motif (en dehors d'une classe de caracte\*`res qui n'est pas affecte\*'e par \f(CW\*(C`/x\*(C'\fR), vous devez les pre\*'ce\*'der d'un caracte\*`re d'e\*'chappement ou les coder en octal ou en hexade\*'cimal. Prises ensembles, ces fonctionnalite\*'s rendent les expressions rationnelles de Perl plus lisibles. Faites attention a\*` ne pas inclure le de\*'limiteur de motif dans un commentaire (perl n'a aucun moyen de savoir que vous ne vouliez pas terminer le motif si to\*^t). Voir le code de suppression des commentaires C dans perlop. .Sh "Expressions rationnelles" .IX Subsection "Expressions rationnelles" Les motifs utilise\*'s par la mise en correspondance de motifs sont des expressions rationnelles telles que fournies dans les routines de la Version 8 des expressions rationnelles. En fait, les routines proviennent (de manie\*`re e\*'loigne\*'e) de la re\*'e\*'criture gratuitement redistribuable des routines de la Version 8 par Henry Spencer. Voir \*(L"Version 8 des expressions rationnelles\*(R" pour de plus amples informations. .PP Notamment, les me\*'ta\-caracte\*`res suivants gardent leur sens a\*` la \fIegrep\fR\ : .PP .Vb 7 \& \e Annule le meta\-sens du meta\-caractere qui suit \& ^ Reconnait le debut de la ligne \& . Reconnait n'importe quel caractere (sauf le caractere nouvelle ligne) \& $ Reconnait la fin de la ligne (ou juste avant le caractere nouvelle ligne final) \& | Alternative \& () Groupement \& [] Classe de caracteres .Ve .PP Par de\*'faut, le caracte\*`re \*(L"^\*(R" ne peut reconnai\*^tre que le de\*'but de la ligne et le caracte\*`re \*(L"$\*(R" que la fin (ou juste avant le caracte\*`re nouvelle ligne de la fin) et Perl effectue certaines optimisations en supposant que la chai\*^ne ne contient qu'une seule ligne. Les caracte\*`res nouvelle ligne inclus ne seront donc pas reconnus par \*(L"^\*(R" ou \*(L"$\*(R". Il est malgre\*' tout possible de traiter une chai\*^ne multi-lignes afin que \*(L"^\*(R" soit reconnu juste apre\*`s n'importe quel caracte\*`re nouvelle ligne et \*(L"$\*(R" juste avant. Pour ce faire, au prix d'un le\*'ger ralentissement, vous devez utiliser le modificateur \f(CW\*(C`/m\*(C'\fR dans l'ope\*'rateur de reconnaissance de motif. (Les anciens programmes obtenaient ce re\*'sultat en positionnant \f(CW$*\fR mais cette pratique est maintenant de\*'sapprouve\*'e.) .PP Pour faciliter les substitutions multi\-lignes, le me\*'ta\-caracte\*`re \*(L".\*(R" ne reconnai\*^t jamais un caracte\*`re nouvelle ligne a\*` moins d'utiliser le modificateur \f(CW\*(C`/s\*(C'\fR qui demande a\*` Perl de conside\*'rer la chai\*^ne comme une seule ligne me\*^me si ce n'est pas le cas. Le modificateur \f(CW\*(C`/s\*(C'\fR passe outre le re\*'glage de \f(CW$*\fR au cas ou\*` vous auriez quelques vieux codes qui le positionnerait dans un autre module. .PP Les quantificateurs standards suivants sont reconnus\ : .PP .Vb 6 \& * Reconnait 0 fois ou plus \& + Reconnait 1 fois ou plus \& ? Reconnait 0 ou 1 fois \& {n} Reconnait n fois exactement \& {n,} Reconnait au moins n fois \& {n,m} Reconnait au moins n fois mais pas plus de m fois .Ve .PP (Si une accolade apparai\*^t dans n'importe quel autre contexte, elle est traite\*'e comme un caracte\*`re normal.) Le quantificateur \*(L"*\*(R" est e\*'quivalent a\*` \f(CW\*(C`{0,}\*(C'\fR, le quantificateur \*(L"+\*(R" a\*` \f(CW\*(C`{1,}\*(C'\fR et le quantificateur \*(L"?\*(R" a\*` \f(CW\*(C`{0,1}\*(C'\fR. n et m sont limite\*'s a\*` des valeurs entie\*`res (!) infe\*'rieures a\*` une valeur fixe\*'e lors de la compilation de perl. Habituellement cette valeur est 32766 sur la plupart des plates\-formes. La limite re\*'elle peut e\*^tre trouve\*'e dans le message d'erreur engendre\*' par le code suivant\ : .PP .Vb 1 \& $_ **= $_ , / {$_} / for 2 .. 42; .Ve .PP Par de\*'faut, un sous-motif quantifie\*' est X\ gourmand\ X, c'est a\*` dire qu'il essaie de se reconnai\*^tre un maximum de fois (a\*` partir d'un point de de\*'part donne\*') sans empe\*^cher la reconnaissance du reste du motif. Si vous voulez qu'il tente de se reconnai\*^tre un minimum de fois, il faut ajouter le caracte\*`re \*(L"?\*(R" juste apre\*`s le quantificateur. Sa signification ne change pas. Seule sa X\ gourmandise\ X change\ : .PP .Vb 6 \& *? Reconnait 0 fois ou plus \& +? Reconnait 1 fois ou plus \& ?? Reconnait 0 ou 1 fois \& {n}? Reconnait n fois exactement \& {n,}? Reconnait au moins n fois \& {n,m}? Reconnait au moins n fois mais pas plus de m fois .Ve .PP Puisque les motifs sont traite\*'s comme des chai\*^nes entre guillemets, les se\*'quences suivantes fonctionnent\ : .PP .Vb 10 \& \et tabulation (HT, TAB) \& \en nouvelle ligne (LF, NL) \& \er retour chariot (CR) \& \ef page suivante (FF) \& \ea alarme (bip) (BEL) \& \ee escape (pensez a troff)(ESC) \& \e033 caractere en octal (pensez au PDP\-11) \& \ex1B caractere hexadecimal \& \ex{263a} caractere hexadecimal etendu (Unicode SMILEY) \& \ec[ caractere de controle \& \eN{nom} caractere nomme \& \el converti en minuscule le caractere suivant (pensez a vi) \& \eu converti en majuscule le caractere suivant (pensez a vi) \& \eL converti en minuscule jusqu'au prochain \eE (pensez a vi) \& \eU converti en majuscule jusqu'au prochain \eE (pensez a vi) \& \eE fin de modification de casse (pensez a vi) \& \eQ desactive les meta\-caracteres de motif jusqu'au prochain \eE .Ve .PP Si \f(CW\*(C`use locale\*(C'\fR est actif, la table de majuscules/minuscules utilise\*'e par \&\f(CW\*(C`\el\*(C'\fR, \f(CW\*(C`\eL\*(C'\fR, \f(CW\*(C`\eu\*(C'\fR et \f(CW\*(C`\eU\*(C'\fR est celle du locale courant. Voir perllocale. Pour de la documentation concernant \f(CW\*(C`\eN{nom}\*(C'\fR, voir charnames. .PP Vous ne pouvez pas inclure litte\*'ralement les caracte\*`res \f(CW\*(C`$\*(C'\fR et \f(CW\*(C`@\*(C'\fR a\*` l'inte\*'rieur d'une se\*'quence \f(CW\*(C`\eQ\*(C'\fR. Tels quels, ils se re\*'fe\*'reraient a\*` la variable correspondante. Pre\*'ce\*'de\*'s d'un \f(CW\*(C`\e\*(C'\fR, ils correspondraient a\*` la chai\*^ne \&\f(CW\*(C`\e$\*(C'\fR ou \f(CW\*(C`\e@\*(C'\fR. Vous e\*^tes oblige\*'s d'e\*'crire quelque chose comme \&\f(CW\*(C`m/\eQuser\eE\e@\eQhost/\*(C'\fR. .PP Perl de\*'finit aussi les se\*'quences suivantes\ : .PP .Vb 11 \& \ew Reconnait un caractere de "mot" (alphanumerique plus "_") \& \eW Reconnait un caractere de non "mot" \& \es Reconnait un caractere d'espace. \& \eS Reconnait un caractere autre qu'un espace \& \ed Reconnait un chiffre \& \eD Reconnait un caractere autre qu'un chiffre \& \epP Reconnait la propriete P (nommee). Utilisez \ep{Prop} \& pour des noms longs \& \eX Reconnait le sequence de caractere Unicode etendue \& equivalent a (?:\e\ePM\epM*) \& \eC Reconnait un caractere d'un seul octet meme sous utft8. .Ve .PP \&\f(CW\*(C`\ew\*(C'\fR reconnai\*^t un seul caracte\*`re alphanume\*'rique ou \f(CW\*(C`_\*(C'\fR, pas a\*` un mot entier. Pour reconnai\*^tre un mot entier au sens des identificateurs Perl, vous devez utiliser \f(CW\*(C`\ew+\*(C'\fR (ce qui n'est pas la me\*^me chose que reconnai\*^tre les mots anglais ou franc\*,ais). Si \f(CW\*(C`use locale\*(C'\fR est actif, la liste de caracte\*`res alphanume\*'riques utilise\*'s par \f(CW\*(C`\ew\*(C'\fR de\*'pend du locale courant. Voir perllocale. Vous pouvez utiliser \f(CW\*(C`\ew\*(C'\fR, \f(CW\*(C`\eW\*(C'\fR, \f(CW\*(C`\es\*(C'\fR, \f(CW\*(C`\eS\*(C'\fR, \f(CW\*(C`\ed\*(C'\fR, et \&\f(CW\*(C`\eD\*(C'\fR a\*` l'inte\*'rieur d'une classe de caracte\*`res mais si vous essayez des les utiliser comme borne d'un intervalle, ce n'est plus un intervalle et le \*(L"\-\*(R" est compris litte\*'ralement. Voir utf8 pour les de\*'tails a\*` propos de \f(CW\*(C`\epP\*(C'\fR, \&\f(CW\*(C`\ePP\*(C'\fR et \f(CW\*(C`\eX\*(C'\fR. .PP La syntaxe \s-1POSIX\s0 des classes de caracte\*`res\ : .PP .Vb 1 \& [:class:] .Ve .PP est aussi disponible. Les classes disponibles et leur e\*'quivalent via la barre oblique inverse\*'e (si il existe) sont les suivants\ : .PP .Vb 10 \& alpha \& alnum \& ascii \& blanck [1] \& cntrl \& digit \ed \& graph \& lower \& print \& punct \& space \es [2] \& upper \& word \ew [3] \& xdigit .Ve .PP [1] Une extension \s-1GNU\s0 e\*'quivalente a\*` \f(CW\*(C`[ \et]\*(C'\fR (tous les espaces horizontaux). .PP [2] Pas excatement e\*'quivalent a\*` \f(CW\*(C`\es\*(C'\fR puisqu \f(CW\*(C`[[:space:]]\*(C'\fR inclut aussi le (tre\*`s rare) tabulateur vertical : \f(CW"\eck"\fR ou \f(CW\*(C`chr(11)\*(C'\fR. .PP [3] Une extension Perl .PP Par exemple, utilisez \f(CW\*(C`[:upper:]\*(C'\fR pour reconnai\*^tre tous les caracte\*`res minuscules. Remarquez que les crochets (\f(CW\*(C`[]\*(C'\fR) font partie de la construction \&\f(CW\*(C`[::]\*(C'\fR et non de la classe de caracte\*`res. Par exemple\ : .PP .Vb 1 \& [01[:alpha:]%] .Ve .PP reconnai\*^t les caracte\*`res un, deux, pourcent et tous les caracte\*`res alphabe\*'tiques. .PP Si le pragma \f(CW\*(C`utf8\*(C'\fR est actif, vous aurez les e\*'quivalences suivantes avec les constructions Unicode \ep{}\ : .PP .Vb 10 \& alpha IsAlpha \& alnum IsAlnum \& ascii IsASCII \& blank IsSpace \& cntrl IsCntrl \& digit IsDigit \ed \& graph IsGraph \& lower IsLower \& print IsPrint \& punct IsPunct \& space IsSpace \& IsSpacePerl \es \& upper IsUpper \& word IsWord \& xdigit IsXDigit .Ve .PP Par exemple \f(CW\*(C`[:lower:]\*(C'\fR et \f(CW\*(C`\ep{IsLower}\*(C'\fR sont e\*'quivalents. .PP Si le pragma \f(CW\*(C`utf8\*(C'\fR n'est pas actif mais que le pragma \f(CW\*(C`locale\*(C'\fR l'est, les classes sont corre\*'le\*'es via l'interface \fIisalpha\fR\|(3) (sauf pour 'word' et \&'blank'). .PP Les classes nomme\*'es non e\*'videntes sont\ : .IP "cntrl" 4 .IX Item "cntrl" N'importe quel caracte\*`re de contro\*^le. Ce sont habituellement des caracte\*`res qui ne produisent aucune sortie mais qui, par contre, modifie le terminal\ : par exemple newline (passage a\*` la ligne) et backspace (retour arrie\*`re) sont des caracte\*`res de contro\*^le. Tous les caracte\*`res pour lesquels \fIord()\fR renvoie une valeur infe\*'rieure a\*` 32 sont des caracte\*`res de contro\*^le (avec l'\s-1ASCII\s0, les codages de caracte\*`res \s-1ISO\s0 Latin et Unicode). .IP "graph" 4 .IX Item "graph" N'importe quel caracte\*`re alphanume\*'riques ou de ponctuation (ou spe\*'cial). .IP "print" 4 .IX Item "print" N'importe quel caracte\*`re alphanume\*'riques, de ponctuation (ou spe\*'cial) ou espace. .IP "punct" 4 .IX Item "punct" N'importe quel caracte\*`re de ponctuation (ou spe\*'cial). .IP "xdigit" 4 .IX Item "xdigit" Un chiffre hexade\*'cimal. Bien que peut utile (\f(CW\*(C`[0\-9A\-Fa\-f]\*(C'\fR aurait tre\*`s bien fonctionner), elle est inclue pour la comple\*'tude. .PP Vous pouvez utilisez la ne\*'gation d'une classe de caracte\*`res [::] en pre\*'fixant son nom par un '^'. C'est une extension de Perl. Par exemple\ : .PP .Vb 1 \& POSIX trad. Perl utf8 Perl \& \& [:^digit:] \eD \eP{IsDigit} \& [:^space:] \eS \eP{IsSpace} \& [:^word:] \eW \eP{IsWord} .Ve .PP Les classes de caracte\*`res \s-1POSIX\s0 [.cc.] et [=cc=] sont reconnues \fBsans\fR e\*^tre supporte\*'es. Une tentative d'utilisation de ces classes provoquera une erreur. .PP Perl de\*'finit les assertions de longueur nulle suivantes\ : .PP .Vb 8 \& \eb Reconnait la limite d'un mot \& \eB Reconnait autre chose qu'une limite de mot \& \eA Reconnait uniquement le debut de la chaine \& \eZ Reconnait uniquement la fin de la chaine (ou juste avant le \& caractere de nouvelle ligne final) \& \ez Reconnait uniquement la fin de la chaine \& \eG Reconnait l'endroit ou s'est arrete le precedent m//g \& (ne fonctionne qu'avec /g) .Ve .PP Une limite de mot (\f(CW\*(C`\eb\*(C'\fR) est de\*'finie comme le point entre deux caracte\*`res qui sont d'un co\*^te\*' un \f(CW\*(C`\ew\*(C'\fR et de l'autre un \f(CW\*(C`\eW\*(C'\fR (dans n'importe quel ordre). Le de\*'but et la fin de la chai\*^ne correspondent a\*` des caracte\*`res imaginaires de type \f(CW\*(C`\eW\*(C'\fR. (A\*` l'inte\*'rieur d'une classe de caracte\*`res, \f(CW\*(C`\eb\*(C'\fR repre\*'sente le caracte\*`re \*(L"backspace\*(R" au lieu d'une limite de mot.) \f(CW\*(C`\eA\*(C'\fR et \f(CW\*(C`\eZ\*(C'\fR agissent exactement comme \*(L"^\*(R" et \*(L"$\*(R" sauf qu'ils ne reconnaissent pas les lignes multiples quand le modificateur \f(CW\*(C`/m\*(C'\fR est utilise\*' alors que \*(L"^\*(R" et \*(L"$\*(R" reconnaissent toutes les limites de lignes internes. Pour reconnai\*^tre la fin re\*'elle de la chai\*^ne, en tenant compte du caracte\*`re nouvelle ligne, vous devez utiliser \f(CW\*(C`\ez\*(C'\fR. .PP \&\f(CW\*(C`\eG\*(C'\fR est utilise\*' pour enchai\*^ner plusieurs mises en correspondance (en utilisant \f(CW\*(C`m//g\*(C'\fR). Voir \*(L"Ope\*'rateurs d'expression rationnelle\*(R" in perlop. Il est aussi utile lorsque vous e\*'crivez un analyseur lexicographique a\*` la \f(CW\*(C`lex\*(C'\fR ou lorsque vous avez plusieurs motifs qui doivent reconnai\*^tre des sous\-chai\*^nes successives de votre chai\*^ne. Voir la re\*'fe\*'rence pre\*'ce\*'dente. L'endroit re\*'el a\*` partir duquel \f(CW\*(C`\eG\*(C'\fR va e\*^tre reconnu peut e\*^tre modifie\*' en affectant une nouvelle valeur a\*` \f(CW\*(C`pos()\*(C'\fR. Voir \*(L"pos\*(R" in perlfunc. .PP La construction \f(CW\*(C`(...)\*(C'\fR cre\*'e des zones de me\*'morisation (des sous\-motifs). Pour vous re\*'fe\*'rer au \-ie\*`me sous\-motifs, utilisez \e a\*` l'inte\*'rieur du motif. A\*` l'exte\*'rieur du motif, utilisez toujours \*(L"$\*(R" a\*` la place de \*(L"\e\*(R" devant n. (Bien que la notation \en fonctionne en de rares occasions a\*` l'exte\*'rieur du motif courant, vous ne devriez pas compter dessus. Voir l'avertissement au sujet de \e1 et de \f(CW$1\fR.) Une re\*'fe\*'rence a\*` un sous-motif me\*'morise\*' est appele\*'e une re\*'fe\*'rence arrie\*`re. .PP Vous pouvez utiliser autant de sous-motifs que ne\*'cessaire. Par contre, Perl utilise les se\*'quences \e10, \e11, etc. comme des synonymes de \e010, \e011, etc. (Souvenez\-vous que 0 signifie octal et donc \e011 est le caracte\*`re code\*' par un neuf dans votre jeu de caracte\*`re, une tabulation en \s-1ASCII\s0.) Perl re\*'soud cette ambigui\*:te\*' en interpre\*'tant \e10 comme une re\*'fe\*'rence arrie\*`re uniquement si il y a de\*'ja\*` au moins 10 parenthe\*`ses ouvrantes avant. De me\*^me, \e11 sera une re\*'fe\*'rence arrie\*`re uniquement si il y a au moins onze parenthe\*`ses ouvrantes avant. Et ainsi de suite. Les se\*'quences de \e1 a\*` \e9 sont toujours interpre\*'te\*'es comme des re\*'fe\*'rences arrie\*`res. .PP Exemples\ : .PP .Vb 1 \& s/^([^ ]*) *([^ ]*)/$2 $1/; # echange les deux premiers mots \& \& if (/(.)\e1/) { # trouve le premier caracte\*`re re\*'pe\*'te\*' \& print "'$1' is the first doubled character\en"; \& } \& \& if (/Time: (..):(..):(..)/) { \& $hours = $1; \& $minutes = $2; \& $seconds = $3; \& } .Ve .PP Plusieurs variables spe\*'ciales se re\*'fe\*`rent a\*` des portions de la dernie\*`re reconnaissance. \f(CW$+\fR renvoie le dernier sous-motif entre parenthe\*`ses reconnu. \f(CW$&\fR renvoie le dernier motif reconnu. (\f(CW$0\fR e\*'tait utilise\*' pour le me\*^me usage mais maintenant, il renvoie le nom du programme.) \f(CW$`\fR renvoie tout ce qui est avant le motif reconnu. \f(CW$'\fR renvoie tout ce qui est apre\*`s le motif reconnu. .PP Les variables nume\*'rote\*'es ($1, \f(CW$2\fR, \f(CW$3\fR, etc.) et les variables spe\*'ciales pre\*'ce\*'dentes (\f(CW$+\fR, \f(CW$&\fR, \f(CW$`\fR et \f(CW$'\fR) ont toutes une porte\*'e dynamique jusqu'a\*` la fin du bloc englobant ou jusqu'a\*` la prochaine reconnaissance re\*'ussie selon ce qui arrive en premier. (Voir \*(L"Compound Statements\*(R" in perlsyn.) .PP \&\fBAttention\fR\ : a\*` partir du moment ou\*` perl voit que vous avez besoin de l'une des variables \f(CW$&\fR, \f(CW$`\fR ou \f(CW$'\fR quelque part dans votre programme, il les calculera a\*` chaque reconnaissance de motif et ce pour tous les motifs. Cela peut ralentir votre programme. Le me\*^me me\*'canisme est utilise\*' lors de l'utilisation de \f(CW$1\fR, \f(CW$2\fR, etc.. Ce ralentissement a donc lieu aussi pour les motifs me\*'morisant des sous\-motifs. (Pour e\*'viter ce ralentissement tout en conservant la possibilite\*' de regroupement, utilisez l'extension \f(CW\*(C`(?:...)\*(C'\fR a\*` la place.) Mais si vous n'utilisez pas $&, etc. dans vos scripts alors vos motifs \fIsans\fR me\*'morisation ne seront pas pe\*'nalise\*'s. Donc, e\*'vitez \f(CW$&\fR, \f(CW$'\fR et \f(CW$`\fR si vous le pouvez. Dans le cas contraire (et certains algorithmes en ont re\*'ellement besoin), si vous les utilisez une fois, utilisez-les partout car vous en supportez de\*'ja\*` le cou\*^t. Depuis la version 5.005, \f(CW$&\fR n'est plus aussi cou\*^teux que les deux autres. .PP Les me\*'ta\-caracte\*`res pre\*'ce\*'de\*'s d'un caracte\*`re barre oblique inverse\*'e en Perl sont alphanume\*'riques tels \f(CW\*(C`\eb\*(C'\fR, \f(CW\*(C`\ew\*(C'\fR, \f(CW\*(C`\en\*(C'\fR. A\*` l'inverse d'autres langages d'expressions rationnelles, il n'y a pas de symbole pre\*'ce\*'de\*' d'un caracte\*`re barre oblique inverse\*'e qui ne soit pas alphanume\*'rique. Donc tout ce qui ressemble a\*` \e\e, \e(, \e), \e<, \e>, \e{, ou \e} est toujours interpre\*'te\*' litte\*'ralement et non comme un me\*'ta\-caracte\*`re. Ceci est utilise\*' pour de\*'sactiver (ou XquoterX) les e\*'ventuels me\*'ta\-caracte\*`res pre\*'sents dans une chai\*^ne que vous voulez utiliser comme motif. Tout simplement, il vous suffit de pre\*'ce\*'der tous les caracte\*`re non\-\*(L"mot\*(R" par un caracte\*`re barre oblique inverse\*'e\ : .PP .Vb 1 \& $pattern =~ s/(\eW)/\e\e$1/g; .Ve .PP (Si \f(CW\*(C`use local\*(C'\fR est actif alors le re\*'sultat de\*'pend de votre locale courant.) Aujourd'hui, il est encore plus simple d'utiliser soit le fonction \fIquotemeta()\fR soit la se\*'quence \f(CW\*(C`\eQ\*(C'\fR pour de\*'sactiver les e\*'ventuels me\*'ta\-caracte\*`res\ : .PP .Vb 1 \& /$unquoted\eQ$quoted\eE$unquoted/ .Ve .PP Sachez que si vous placez un backspace litte\*'rale (ceux qui ne sont pas dans des variables interpole\*'es) entre \f(CW\*(C`\eQ\*(C'\fR et \f(CW\*(C`\eE\*(C'\fR, l'interpolation peut vous amener des re\*'sultats tre\*`s e\*'tonnants. Si vous avez \fIbesoin\fR de constructions de ce genre, consultez \*(L"Les de\*'tails sordides de l'interpre\*'tation des chai\*^nes\*(R" in perlop .Sh "Motifs e\*'tendus" .IX Subsection "Motifs e'tendus" Perl de\*'finit une syntaxe logique d'extension des expressions rationnelles pour ajouter les fonctionnalite\*'s inexistantes dans les outils standard comme \fBawk\fR et \fBlex\fR.. La syntaxe est une paire de parenthe\*`ses avec un point d'interrogation comme premier caracte\*`re entre les parenthe\*`ses. Le caracte\*`re qui suit le point d'interrogation pre\*'cise la fonction de l'extension. .PP La stabilite\*' de ces extensions varient e\*'norme\*'ment. Certaine font partie du langage depuis de longues anne\*'es. D'autres sont encore expe\*'rimentales et peuvent changer sans avertissement ou me\*^me e\*^tre retire\*'es comple\*`tement. Ve\*'rifier le documentation de chacune de ces extensions pour connai\*^tre leur e\*'tat. .PP Le point d'interrogation a e\*'te\*' choisi pour les extensions ainsi que pour les modificateurs non gourmands parce que 1) les points d'interrogation sont rares dans les vieilles expressions rationnelles et 2) pour qu'a\*` chaque fois que vous en voyez un, vous vous arre\*^tiez pour vous \*(L"interroger\*(R" sur son comportement. C'est psychologique... .ie n .IP """(?#texte)""" 10 .el .IP "\f(CW(?#texte)\fR" 10 .IX Item "(?#texte)" Un commentaire. Le texte est ignore\*'. Si le modificateur \f(CW\*(C`/x\*(C'\fR est utilise\*' pour autoriser la mise en forme avec des blancs, un simple \f(CW\*(C`#\*(C'\fR devrait suffire. Notez que Perl termine le commentaire aussito\*^t qu'il rencontre \&\f(CW\*(C`)\*(C'\fR. Il n'y a donc aucun moyen de mettre le caracte\*`re \f(CW\*(C`)\*(C'\fR dans ce commentaire. .ie n .IP """(?imsx\-imsx)""" 10 .el .IP "\f(CW(?imsx\-imsx)\fR" 10 .IX Item "(?imsx-imsx)" Un ou plusieurs modificateurs de motifs inte\*'gre\*'s. C'est particulie\*`rement pratique pour les motifs dynamiques tels ceux lus depuis un fichier de configuration, ceux provenant d'un argument ou ceux qui sont spe\*'cifie\*'s dans une table quelque part. Certains devront e\*^tre sensibles a\*` la casse, d'autres non. Dans le cas ou\*` un motif ne doit pas e\*^tre sensible a\*` la casse, il est possible d'inclure \f(CW\*(C`(?i\*(C'\fR) au de\*'but du motif. Par exemple\ : .Sp .Vb 2 \& $pattern = "foobar"; \& if ( /$pattern/i ) { } \& \& # plus flexible : \& \& $pattern = "(?i)foobar"; \& if ( /$pattern/ ) { } .Ve .Sp Les lettres apre\*`s le \f(CW\*(C`\-\*(C'\fR de\*'sactive les modificateurs correspondants. Ces modificateurs sont locaux au groupe englobant (si il existe). Par exemple\ : .Sp .Vb 1 \& ( (?i) blah ) \es+ \e1 .Ve .Sp reconnai\*^tra un mot \f(CW\*(C`blah\*(C'\fR re\*'pe\*'te\*' (\fIy compris sa casse\fR !) (en supposant le modificateur \f(CW\*(C`x\*(C'\fR et aucun modificateur \f(CW\*(C`i\*(C'\fR a\*` l'exte\*'rieur du groupe). .ie n .IP """(?:motif)""" 10 .el .IP "\f(CW(?:motif)\fR" 10 .IX Item "(?:motif)" .PD 0 .ie n .IP """(?imsx\-imsx:motif)""" 10 .el .IP "\f(CW(?imsx\-imsx:motif)\fR" 10 .IX Item "(?imsx-imsx:motif)" .PD C'est pour regrouper et non pas me\*'moriser. Cela permet de regrouper des sous-expressions comme \*(L"()\*(R" mais sans permettre les re\*'fe\*'rences arrie\*`re. Donc\ : .Sp .Vb 1 \& @fields = split(/\eb(?:a|b|c)\eb/) .Ve .Sp est similaire a\*` .Sp .Vb 1 \& @fields = split(/\eb(a|b|c)\eb/) .Ve .Sp mais ne produit pas de me\*'morisations supple\*'mentaires. C'est moins couteux de ne pas me\*'moriser des caracte\*`res si vous n'en avez pas besoin. .Sp Les lettres entre \f(CW\*(C`?\*(C'\fR et \f(CW\*(C`:\*(C'\fR agissent comme des modificateurs. Voir \&\f(CW\*(C`(?imsx\-imsx)\*(C'\fR. Par exemple\ : .Sp .Vb 1 \& /(?s\-i:more.*than).*million/i .Ve .Sp est e\*'quivalent a\*` .Sp .Vb 1 \& /(?:(?s\-i)more.*than).*million/i .Ve .ie n .IP """(?=motif)""" 10 .el .IP "\f(CW(?=motif)\fR" 10 .IX Item "(?=motif)" Une assertion de longueur nulle pour tester la pre\*'sence de quelque chose en avant. Par exemple, \f(CW\*(C`/\ew+(?=\et)/\*(C'\fR reconnai\*^t un mot suivit d'une tabulation sans inclure cette tabulation dans \f(CW$&\fR. .ie n .IP """(?!motif)""" 10 .el .IP "\f(CW(?!motif)\fR" 10 .IX Item "(?!motif)" Une assertion de longueur nulle pour tester l'absence de quelque chose en avant. Par exemple, \f(CW\*(C`/foo(?!bar)/\*(C'\fR reconnai\*^t toutes les occurrences de \*(L"foo\*(R" qui ne sont pas suivies de \*(L"bar\*(R". Notez bien que regarder en avant n'est pas la me\*^me chose que regarder en arrie\*`re (!). Vous ne pouvez pas utiliser cette assertion pour regarder en arrie\*`re. .Sp Si vous cherchez un \*(L"bar\*(R" qui ne soit pas pre\*'ce\*'de\*' par \*(L"foo\*(R", \f(CW\*(C`/(?!foo)bar/\*(C'\fR ne vous donnera pas ce que vous voulez. C'est parce que \f(CW\*(C`(?!foo)\*(C'\fR exige seulement que ce qui suit ne soit pas \*(L"foo\*(R" \*(-- et c\*,a ne l'est pas puisque c'est \*(L"bar\*(R", donc \*(L"foobar\*(R" sera accepte\*'. Vous devez alors utilisez quelque chose comme \f(CW\*(C`/(?!foo)...bar/\*(C'\fR. Nous disons \*(L"comme\*(R" car il se peut que \*(L"bar\*(R" ne soit pas pre\*'ce\*'de\*' par trois caracte\*`res. Vous pouvez alors utiliser \&\f(CW\*(C`/(?:(?!foo)...|^.{0,2})bar/\*(C'\fR. Parfois, il est quand me\*^me plus simple de dire\ : .Sp .Vb 1 \& if (/bar/ && $` !~ /foo$/) .Ve .Sp Pour regarder en arrie\*`re, voir plus loin. .ie n .IP """(?<=motif)""" 10 .el .IP "\f(CW(?<=motif)\fR" 10 .IX Item "(?<=motif)" Une assertion de longueur nulle pour tester la pre\*'sence de quelque chose en arrie\*`re. Par exemple, \f(CW\*(C`/(?<=\et)\ew+/\*(C'\fR reconnai\*^t un mot qui suit une tabulation sans inclure cette tabulation dans \f(CW$&\fR. Cela ne fonctionne qu'avec un motif de longueur fixe. .ie n .IP """(?x; .Ve .Sp produit \f(CW\*(C`$res = 4\*(C'\fR. Remarquez qu'apre\*`s la reconnaissance, \f(CW$cnt\fR revient a\*` la valeur 0 affecte\*'e globalement puisque nous ne sommes plus dans la porte\*'e du bloc ou\*` l'appel a\*` \f(CW\*(C`local\*(C'\fR est effectue\*'. .Sp Cette assertion peut e\*^tre utilise\*'e comme se\*'lecteur: \&\f(CW\*(C`(?(condition)motif\-oui|motif\-non)\*(C'\fR. Si elle n'est \fIpas\fR utilise\*'e comme cela, le re\*'sultat de l'e\*'valuation du \f(CW\*(C`code\*(C'\fR est affecte\*' a\*` la variable $^R. L'affectation est imme\*'diate donc $^R peut\-e\*^tre utilise\*' a\*` partir d'une autre assertion de type \f(CW\*(C`(?{ code })\*(C'\fR a\*` l'inte\*'rieur de la me\*^me expression rationnelle. .Sp L'affectation a\*` $^R est correctement localise\*'e, par conse\*'quent l'ancienne valeur de $^R est restaure\*'e en cas de retour arrie\*`re (voir \&\*(L"Retour arrie\*`re\*(R"). .Sp Pour des raisons de se\*'curite\*', cette construction n'est pas autorise\*'e si l'expression rationnelle ne\*'cessite une interpolation de variables lors de l'exe\*'cution sauf si vous utilisez le directive \f(CW\*(C`use re 'eval'\*(C'\fR (voir re) ou si la variable contient le re\*'sultat de l'ope\*'rateur \fIqr()\fR (voir \&\*(L"qr/STRING/imosx\*(R" in perlop). .Sp Cette restriction est due a\*` l'usage tre\*`s courant et remarquablement pratique de motifs de\*'termine\*'s lors de l'exe\*'cution. Par exemple\ : .Sp .Vb 3 \& $re = <>; \& chomp $re; \& $string =~ /$re/; .Ve .Sp Avant que Perl sache comment exe\*'cuter du code interpole\*' a\*` l'inte\*'rieur d'un motif, cette ope\*'ration e\*'tait comple\*`tement su\*^re d'un point de vue se\*'curite\*' bien qu'elle puisse ge\*'ne\*'rer une exception si le motif n'est pas le\*'gal. Par contre, si vous activez la directive \f(CW\*(C`use re 'eval'\*(C'\fR, cette construction n'est plus du tout su\*^re. Vous ne devriez donc le faire que lorsque vous utilisez la ve\*'rification des donne\*'es (via taint et l'option \f(CW\*(C`\-T\*(C'\fR). Mieux encore, vous pouvez utiliser une e\*'valuation contrainte via le module Safe. Voir perlsec pour les de\*'tails a\*` propos de ces me\*'canismes. .ie n .IP """(??{ code })""" 10 .el .IP "\f(CW(??{ code })\fR" 10 .IX Item "(??{ code })" \&\fB\s-1ATTENTION\s0\fR\ : cette extension est conside\*'re\*'e comme expe\*'rimentale. Elle peut e\*'voluer voir me\*^me disparai\*^tre sans pre\*'avis. Une version simplifie\*'e de la syntaxe pourrait e\*^tre introduite pour les cas les plus courants. .Sp C'est un sous-motif d'expression rationnelle a\*` \*(L"e\*'valuation retarde\*'e\*(R". Le \&\f(CW\*(C`code\*(C'\fR est e\*'value\*' lors de l'exe\*'cution au moment ou\*` le sous-motif est reconnu. Le re\*'sultat de l'e\*'valuation est conside\*'re\*' comme une expression rationnelle dont on doit tenter la reconnaissance comme si elle remplac\*,ait la construction. .Sp Le \f(CW\*(C`code\*(C'\fR n'est pas interpole\*'. Comme pre\*'ce\*'demment, les re\*`gles pour de\*'terminer l'endroit ou\*` se termine le \f(CW\*(C`code\*(C'\fR sont un peu complique\*'es. .Sp La motif suivant reconnai\*^t des groupes parenthe\*'se\*'s\ : .Sp .Vb 9 \& $re = qr{ \& \e( \& (?: \& (?> [^()]+ ) # Non\-parens without backtracking \& | \& (??{ $re }) # Group with matching parens \& )* \& \e) \& }x; .Ve .ie n .IP """(?>motif)""" 10 .el .IP "\f(CW(?>motif)\fR" 10 .IX Item "(?>motif)" \&\fB\s-1ATTENTION\s0\fR\ : cette extension est conside\*'re\*'e comme expe\*'rimentale. Elle peut e\*'voluer voir me\*^me disparai\*^tre sans pre\*'avis. .Sp Une sous-expression \*(L"inde\*'pendante\*(R". Reconnai\*^t \fBuniquement\fR la sous\-chai\*^ne qui aurait e\*'te\*' reconnue si la sous-expression avait e\*'te\*' seule et ancre\*'e au me\*^me endroit. C'est pratique, par exemple pour optimiser certaines constructions qui risqueraient sinon d'e\*^tre \*(L"e\*'ternelles\*(R", car cette construction n'effectue aucun retour arrie\*`re (voir \*(L"Retour arrie\*`re\*(R"). C'est aussi pratique la\*` ou\*` on a besoin de la se\*'mantique \*(L"prend tout ce que tu peux sans jamais redonner quoique ce soit\*(R". .Sp Par exemple\ : \f(CW\*(C`^(?>a*)ab\*(C'\fR ne pourra jamais e\*^tre reconnu puisque \&\f(CW\*(C`(?>a*)\*(C'\fR (ancre\*' au de\*'but de la chai\*^ne) reconnai\*^tra \fItous\fR les caracte\*`res \&\f(CW\*(C`a\*(C'\fR du de\*'but de la chai\*^ne en ne laissant aucun \f(CW\*(C`a\*(C'\fR pour reconnai\*^tre \f(CW\*(C`ab\*(C'\fR. A contrario, \f(CW\*(C`a*ab\*(C'\fR reconnai\*^tra la me\*^me chose que \f(CW\*(C`a+b\*(C'\fR puisque la reconnaissance du sous-groupe \f(CW\*(C`a*\*(C'\fR est influence\*' par le groupe suivant \f(CW\*(C`ab\*(C'\fR (voir \*(L"Retour arrie\*`re\*(R"). En particulier, \f(CW\*(C`a*\*(C'\fR dans \f(CW\*(C`a*ab\*(C'\fR reconnai\*^t moins de caracte\*`res que \f(CW\*(C`a*\*(C'\fR seul puisque cela permet a\*` la suite d'e\*^tre reconnue. .Sp Un effet similaire a\*` \f(CW\*(C`(?>motif)\*(C'\fR peut e\*^tre obtenu en e\*'crivant \&\f(CW\*(C`(?=(motif))\e1\*(C'\fR. La recherche est effectue\*'e dans un contexte \fI\*(L"logique\*(R"\fR et reconnai\*^t donc la me\*^me sous\-chai\*^ne qu'une expression \f(CW\*(C`a+\*(C'\fR seule. Le \f(CW\*(C`\e1\*(C'\fR mange la chai\*^ne reconnue et transforme donc l'assertion de longueur nulle en une expression analogue a\*` \f(CW\*(C`(?>...)\*(C'\fR. (La seule diffe\*'rence est que la dernie\*`re utilise un groupe me\*'morise\*' et de\*'cale donc le nume\*'ro des re\*'fe\*'rences arrie\*`res dans le reste de l'expression rationnelle.) .Sp Supposons le motif suivant\ : .Sp .Vb 8 \& m{ \e( \& ( \& [^()]+ # x+ \& | \& \e( [^()]* \e) \& )+ \& \e) \& }x .Ve .Sp L'exemple pre\*'ce\*'dent reconnai\*^t de manie\*`re efficace un groupe non-vide qui contient au plus deux niveaux de parenthe\*`ses. Par contre, si un tel groupe n'existe pas, cela prendra un temps potentiellement infini sur une longue chai\*^ne car il existe e\*'norme\*'ment de manie\*`res diffe\*'rentes de de\*'couper une chai\*^ne en sous\-chai\*^nes. C'est ce que fait \f(CW\*(C`(.+)+\*(C'\fR qui est similaire a\*` l'un des sous-motifs du motif pre\*'ce\*'dent. Rendez-vous compte que l'expression pre\*'ce\*'dente de\*'tecte la non reconnaissance sur \f(CW\*(C`((()aaaaaaaaaaaaaaaaaa\*(C'\fR en quelques secondes mais que chaque lettre supple\*'mentaire multiplie ce temps par deux. Cette augmentation exponentielle du temps d'exe\*'cution peut faire croire que votre programme est plante\*'. Par contre, le me\*^me motif tre\*`s le\*'ge\*`rement modifie\*'\ : .Sp .Vb 8 \& m{ \e( \& ( \& (?> [^()]+ ) # remplacement de x+ par (?> x+ ) \& | \& \e( [^()]* \e) \& )+ \& \e) \& }x .Ve .Sp pour utiliser \f(CW\*(C`(?>...)\*(C'\fR, reconnai\*^t exactement la me\*^me chose (un bon exercice serait de la ve\*'rifier vous\-me\*^me) mais se termine en 4 fois moins de temps sur une chai\*^ne similaire contenant 1000000 \f(CW\*(C`a\*(C'\fR. Attention, ce motif produit actuellement un message d'avertissement avec \fB\-w\fR disant \f(CW"matches the null string many times"\fR (\f(CW"reconnai\*^t la chai\*^ne de longueur nulle tre\*`s souvent"\fR). .Sp Dans des motifs simples comme \f(CW\*(C`(?> [^()]+ )\*(C'\fR, un effet comparable peut e\*^tre observe\*' en utilisant le test d'absence en avant comme dans \f(CW\*(C`[^()]+ (?! [^()] )\*(C'\fR. Ce n'est que 4 fois plus lent sur une chai\*^ne contenant 1000000 \&\f(CW\*(C`a\*(C'\fR. .Sp La se\*'mantique \*(L"prend tout ce que tu peux sans jamais redonner quoique ce soit\*(R" est utile dans de nombreuses situations ou\*` une premie\*`re analyse laisse a\*` penser qu'un simple motif \f(CW\*(C`()*\*(C'\fR suffit. Supposez que vous voulez analyser un texte avec des commentaires de\*'limite\*'s par \f(CW\*(C`#\*(C'\fR suivi d'e\*'ventuels espaces (horizontaux). Contrairement aux apparences, \f(CW\*(C`#[ \et]*\*(C'\fR n'est \fIpas\fR le sous-motif correct pour reconnai\*^tre le de\*'limiteur de commentaires parce qu'il peut laisser e\*'chapper quelques espaces si la suite du motif en a besoin pour e\*^tre reconnue. Le re\*'ponse correcte est l'une de celles qui suivent\ : .Sp .Vb 2 \& (?>#[ \et]*) \& #[ \et]*(?![ \et]) .Ve .Sp Par exemple, pour obtenir tous les commentaires non vides dans \f(CW$1\fR, il vous faut utiliser l'une de ces constructions\ : .Sp .Vb 2 \& / (?> \e# [ \et]* ) ( .+ ) /x; \& / \e# [ \et]* ( [^ \et] .* ) /x; .Ve .Sp La meilleure des deux est celle qui correspondrait le mieux a\*` la description des commentaires faite par les spe\*'cifications. .ie n .IP """(?(condition)motif\-oui|motif\-non)""" 10 .el .IP "\f(CW(?(condition)motif\-oui|motif\-non)\fR" 10 .IX Item "(?(condition)motif-oui|motif-non)" .PD 0 .ie n .IP """(?(condition)motif\-oui)""" 10 .el .IP "\f(CW(?(condition)motif\-oui)\fR" 10 .IX Item "(?(condition)motif-oui)" .PD \&\fB\s-1ATTENTION\s0\fR\ : cette extension est conside\*'re\*'e comme expe\*'rimentale. Elle peut e\*'voluer voir me\*^me disparai\*^tre sans pre\*'avis. .Sp Expression conditionnelle. \f(CW\*(C`(condition)\*(C'\fR est soit un entier entre parenthe\*`ses (qui est vrai si le sous-motif me\*'morise\*' correspondant reconnai\*^t quelque chose), soit une assertion de longueur nulle (test en arrie\*`re, en avant ou e\*'valuation). .Sp Par exemple\ : .Sp .Vb 4 \& m{ ( \e( )? \& [^()]+ \& (?(1) \e) ) \& }x .Ve .Sp reconnai\*^t une suite de caracte\*`res tous diffe\*'rents des parenthe\*`ses e\*'ventuellement entoure\*'e d'une paire de parenthe\*`ses. .Sh "Retour arrie\*`re" .IX Subsection "Retour arrie`re" \&\s-1NOTE\s0\ : cette section pre\*'sente une abstraction approximative du comportement des expressions rationnelles. Pour une vue plus rigoureuse (et complique\*'e) des re\*`gles utilise\*'es pour choisir entre plusieurs reconnaissances possibles, voir \&\*(L"Combinaison d'expressions rationnelles\*(R". .PP Une particularite\*' fondamentale de la reconnaissance d'expressions rationnelles est lie\*'e a\*` la notion de \fIretour arrie\*`re\fR qui est actuellement utilise\*'e (si ne\*'cessaire) par tous les quantificateurs d'expressions rationnelles. A\*` savoir \&\f(CW\*(C`*\*(C'\fR, \f(CW\*(C`*?\*(C'\fR, \f(CW\*(C`+\*(C'\fR, \f(CW\*(C`+?\*(C'\fR, \f(CW\*(C`{n,m}\*(C'\fR et \f(CW\*(C`{n,m}?\*(C'\fR. Les retours arrie\*`res sont parfois optimise\*'s en interne mais les principes ge\*'ne\*'raux expose\*'s ici restent valides. .PP Pour qu'une expression rationnelle soit reconnue, \fItoute\fR l'expression doit e\*^tre reconnue, pas seulement une partie. Donc si le de\*'but de l'expression rationnelle est reconnue mais de telle sorte qu'elle empe\*^che la reconnaissance de la suite du motif, le moteur de reconnaissance revient en arrie\*`re pour calculer autrement le de\*'but \*(-- d'ou\*` le nom retour arrie\*`re. .PP Voici un exemple de retour arrie\*`re. Supposons que vous voulez trouver le mot qui suit \*(L"foo\*(R" dans la chai\*^ne \*(L"Food is on the foo table.\*(R": .PP .Vb 4 \& $_ = "Food is on the foo table."; \& if ( /\eb(foo)\es+(\ew+)/i ) { \& print "$2 suit $1.\en"; \& } .Ve .PP Lors de la reconnaissance, la premie\*`re partie de l'expression rationnelle (\f(CW\*(C`\eb(foo)\*(C'\fR) trouve un point d'ancrage de\*`s le de\*'but de la chai\*^ne et stocke \&\*(L"Foo\*(R" dans \f(CW$1\fR. Puis le moteur de reconnaissance s'aperc\*,oit qu'il n'y pas de caracte\*`re d'espacement apre\*`s le \*(L"Foo\*(R" qu'il a stocke\*' dans \f(CW$1\fR et, reconnaissant son erreur, il recommence alors un caracte\*`re plus loin que cette premie\*`re tentative. Cette fois, il va jusqu'a\*` la prochaine occurrence de \*(L"foo\*(R", l'ensemble de l'expression rationnelle est reconnue et vous obtenez comme pre\*'vu \*(L"table suit foo.\*(R" .PP Parfois la reconnaissance minimale peut aider. Imaginons que vous voulez reconnai\*^tre tout ce qu'il y a entre \*(L"foo\*(R" et \*(L"bar\*(R". Tout d'abord, vous e\*'crivez quelque chose comme\ : .PP .Vb 4 \& $_ = "The food is under the bar in the barn."; \& if ( /foo(.*)bar/ ) { \& print "got <$1>\en"; \& } .Ve .PP qui, de manie\*`re inattendue, produit\ : .PP .Vb 1 \& got .Ve .PP C'est parce que \f(CW\*(C`.*\*(C'\fR est gourmand. Vous obtenez donc tout ce qu'il y a entre le \fIpremier\fR \*(L"foo\*(R" et le \fIdernier\fR \*(L"bar\*(R". Dans ce cas, la reconnaissance minimale est efficace pour vous garantir de reconnai\*^tre tout ce qu'il y a entre un \*(L"foo\*(R" et le premier \*(L"bar\*(R" qui suit. .PP .Vb 2 \& if ( /foo(.*?)bar/ ) { print "got <$1>\en" } \& got .Ve .PP Voici un autre exemple. Supposons que vous voulez reconnai\*^tre un nombre a\*` la fin d'une chai\*^ne tout en me\*'morisant ce qui pre\*'ce\*`de. Vous e\*'crivez donc\ : .PP .Vb 4 \& $_ = "I have 2 numbers: 53147"; \& if ( /(.*)(\ed*)/ ) { # Rate! \& print "Beginning is <$1>, number is <$2>.\en"; \& } .Ve .PP Cela ne marche pas parce que \f(CW\*(C`.*\*(C'\fR est gourmand et engloutit toute la chai\*^ne. Puisque \f(CW\*(C`\ed*\*(C'\fR peut reconnai\*^tre la chai\*^ne vide, toute l'expression rationnelle est reconnue. .PP .Vb 1 \& Beginning is , number is <>. .Ve .PP Voici quelques variantes dont la plupart ne marche pas\ : .PP .Vb 11 \& $_ = "I have 2 numbers: 53147"; \& @pats = qw{ \& (.*)(\ed*) \& (.*)(\ed+) \& (.*?)(\ed*) \& (.*?)(\ed+) \& (.*)(\ed+)$ \& (.*?)(\ed+)$ \& (.*)\eb(\ed+)$ \& (.*\eD)(\ed+)$ \& }; \& \& for $pat (@pats) { \& printf "%\-12s ", $pat; \& if ( /$pat/ ) { \& print "<$1> <$2>\en"; \& } else { \& print "FAIL\en"; \& } \& } .Ve .PP qui affichera\ : .PP .Vb 8 \& (.*)(\ed*) <> \& (.*)(\ed+) <7> \& (.*?)(\ed*) <> <> \& (.*?)(\ed+) <2> \& (.*)(\ed+)$ <7> \& (.*?)(\ed+)$ <53147> \& (.*)\eb(\ed+)$ <53147> \& (.*\eD)(\ed+)$ <53147> .Ve .PP Comme vous pouvez le constater, c'est un peu de\*'licat. Il faut comprendre qu'une expression rationnelle n'est qu'un ensemble d'assertions donnant une de\*'finition du succe\*`s. Il peut y avoir aucun, un ou de nombreux moyens de re\*'pondre a\*` cette de\*'finition lorsqu'on l'applique a\*` une chai\*^ne particulie\*`re. Et lorsqu'il y a plusieurs moyens, vous devez comprendre le retour arrie\*`re pour savoir quelle varie\*'te\*' de succe\*`s vous obtiendrez. .PP Avec l'utilisation des assertions de tests d'absence ou de pre\*'sence, cela peut devenir carre\*'ment e\*'pineux. Supposons que vous voulez retrouver une suite de caracte\*`res non nume\*'riques suivie par \*(L"123\*(R". Vous pouvez essayer d'e\*'crire quelque chose comme\ : .PP .Vb 4 \& $_ = "ABC123"; \& if ( /^\eD*(?!123)/ ) { # Rate! \& print "Heu, pas de 123 dans $_\en"; \& } .Ve .PP Mais c\*,a ne fonctionne pas... tout du moins pas comme vous l'espe\*'riez. C\*,a affiche qu'il n'y a pas de 123 a\*` la fin de la chai\*^ne. Voici une pre\*'sentation claire de ce que ces motifs reconnaissent contrairement a\*` ce qu'on pourrait attendre\ : .PP .Vb 2 \& $x = 'ABC123' ; \& $y = 'ABC445' ; \& \& print "1: got $1\en" if $x =~ /^(ABC)(?!123)/ ; \& print "2: got $1\en" if $y =~ /^(ABC)(?!123)/ ; \& \& print "3: got $1\en" if $x =~ /^(\eD*)(?!123)/ ; \& print "4: got $1\en" if $y =~ /^(\eD*)(?!123)/ ; .Ve .PP Affiche\ : .PP .Vb 3 \& 2: got ABC \& 3: got AB \& 4: got ABC .Ve .PP On aurait pu croire que le test 3 e\*'chouerait puisqu'il semble e\*^tre une ge\*'ne\*'ralisation du test 1. La diffe\*'rence importante entre les deux est que le test 3 contient un quantificateur (\f(CW\*(C`\eD*\*(C'\fR) et peut donc effectuer des retours arrie\*`re alors que le test 1 ne le peut pas. En fait, ce que demande le test 3 c'est \*(L"existe\-t\-il au de\*'but de \f(CW$x\fR quelque chose qui n'est pas 123 et qui suit 0 ou plusieurs caracte\*`res autres que des chiffres ?\*(R". Si on laisse \f(CW\*(C`\eD*\*(C'\fR reconnai\*^tre \*(L"\s-1ABC\s0\*(R", cela entrai\*^ne l'e\*'chec du motif complet. .PP Le moteur de reconnaissance met tout d'abord en correspondance \f(CW\*(C`\eD*\*(C'\fR avec \&\*(L"\s-1ABC\s0\*(R". Puis il essaie de mettre en correspondance \f(CW\*(C`(?!123)\*(C'\fR avec \*(L"123\*(R", ce qui e\*'videmment e\*'choue. Mais puisque un quantificateur (\f(CW\*(C`\eD*\*(C'\fR) est utilise\*' dans l'expression rationnelle, le moteur de reconnaissance peut faire des retours arrie\*`re pour tenter une reconnaissance diffe\*'rente afin de reconnai\*^tre l'ensemble de l'expression rationnelle. .PP Le motif veut \fIvraiment\fR e\*^tre reconnu, alors il utilise le me\*'canisme de retour arrie\*`re et limite cette fois l'expansion de \f(CW\*(C`\eD*\*(C'\fR juste a\*` \*(L"\s-1AB\s0\*(R". Maintenant, il y a re\*'ellement quelque chose qui suit \*(L"\s-1AB\s0\*(R" et qui n'est pas \&\*(L"123. C'est \*(R"C123" qui est suffisant pour re\*'ussir. .PP On peut faire la me\*^me chose en mixant l'utilisation des assertions de pre\*'sence et d'absence. Nous dirons alors que la premie\*`re partie doit e\*^tre suivie par un chiffre mais doit aussi e\*^tre suivie par quelque chose qui n'est pas \*(L"123\*(R". Souvenez-vous que les tests en avant sont des assertions de longueur nulle \*(-- ils ne font que regarder mais ne consomment pas de caracte\*`res de la chai\*^ne lors de leur reconnaissance. Donc, re\*'e\*'crit comme suit, cela produira le re\*'sultat attendu. C'est a\*` dire que le test 5 e\*'chouera et le 6 marchera\ : .PP .Vb 2 \& print "5: got $1\en" if $x =~ /^(\eD*)(?=\ed)(?!123)/ ; \& print "6: got $1\en" if $y =~ /^(\eD*)(?=\ed)(?!123)/ ; \& \& 6: got ABC .Ve .PP En d'autres termes, cela signifie que les deux assertions de longueur nulle conse\*'cutives doivent e\*^tre vraies toutes les deux ensembles, exactement comme quand vous utilisez des assertions pre\*'de\*'finies: \f(CW\*(C`/^$/\*(C'\fR est reconnue uniquement si vous e\*^tes simultane\*'ment au de\*'but \s-1ET\s0 a\*` la fin de la ligne. La re\*'alite\*' sous-jacente est que la juxtaposition de deux expressions rationnelles signifie toujours un \s-1ET\s0 sauf si vous e\*'crivez explicitement un \s-1OU\s0 en utilisant la barre verticale. \f(CW\*(C`/ab/\*(C'\fR signifie reconnai\*^tre \*(L"a\*(R" \s-1ET\s0 (puis) reconnai\*^tre \&\*(L"b\*(R", me\*^me si les tentatives de reconnaissance n'ont pas lieu a\*` la me\*^me position puisque \*(L"a\*(R" n'est pas une assertion de longueur nulle (mais de longueur un). .PP \&\fBAvertissement\fR\ : certaines expressions rationnelles complique\*'es peuvent prendre un temps exponentiel pour leur re\*'solution a\*` cause du grand nombre de retours arrie\*`re effectue\*'s pour essayer d'e\*^tre reconnue. Par exemple, sans les optimisations internes du moteur d'expressions rationnelles, l'expression suivante calculerait tre\*`s longtemps\ : .PP .Vb 1 \& 'aaaaaaaaaaaa' =~ /((a{0,5}){0,5})*[c]/ .Ve .PP et si vous utilisiez des \f(CW\*(C`*\*(C'\fR au lieu de limiter entre 0 et 5 reconnaissances, elle pourrait alors prendre litte\*'ralement un temps infini \*(-- ou pluto\*^t jusqu'au de\*'passement de la capacite\*' de la pile. De plus, ces optimisations ne sont pas toujours applicables. Par exemple, en remplac\*,ant \f(CW\*(C`{0,5}\*(C'\fR par \f(CW\*(C`*\*(C'\fR dans le groupe externe, plus aucune optimisation n'a lieu et le calcul devient extre\*^mement long. .PP Un outil puissant pour optimiser ce genre de choses est les groupes \&\*(L"inde\*'pendants\*(R" qui n'effectuent pas de retour arrie\*`re (voir \&\f(CW\*(C`(?>motif)\*(C'\fR). Remarquez aussi que les assertions de longueur nulle n'effectuent pas de retour arrie\*`re puisqu'elles sont conside\*'re\*'es dans un contexte \*(L"logique\*(R"\ : seul importe qu'elles soient reconnaissables ou non. Pour un exemple de l'influence e\*'ventuelle sur la reconnaissance voir \&\f(CW\*(C`(?>motif)\*(C'\fR. .Sh "Version 8 des expressions rationnelles" .IX Subsection "Version 8 des expressions rationnelles" Si vous n'e\*^tes pas familier avec la version 8 des expressions rationnelles, vous trouverez ici les re\*`gles de reconnaissance de motifs qui n'ont pas e\*'te\*' de\*'crites plus haut. .PP Un caracte\*`re se reconnai\*^t lui\-me\*^me sauf si c'est un me\*'ta\-caracte\*`re avec un sens spe\*'cial de\*'crit ici ou pre\*'ce\*'demment. Pour interpre\*'ter un me\*'ta\-caracte\*`re litte\*'ralement, il faut le pre\*'fixer par un \*(L"\e\*(R" (e.g., \*(L"\e.\*(R" reconnai\*^t un \*(L".\*(R" au lieu de n'importe quel caracte\*`re, \*(L"\e\e\*(R" reconnai\*^t \*(L"\e\*(R"). Une suite de caracte\*`res reconnai\*^t cette suite de caracte\*`res dans la chai\*^ne a\*` analyser. Le motif \&\f(CW\*(C`blurfl\*(C'\fR reconnai\*^tra donc \*(L"blurfl\*(R" dans la chai\*^ne a\*` analyser. .PP Vous pouvez spe\*'cifier une classe de caracte\*`res en entourant une liste de caracte\*`res entre \f(CW\*(C`[]\*(C'\fR. Cette classe reconnai\*^tra l'un des caracte\*`res de la liste. Si le premier caracte\*`re apre\*`s le \*(L"[\*(R" est \*(L"^\*(R", la classe reconnai\*^tra un caracte\*`re qui n'est pas dans la liste. A\*` l'inte\*'rieur d'une liste, la caracte\*`re \&\*(L"\-\*(R" sert a\*` de\*'crire un intervalle. Par exemple \f(CW\*(C`a\-z\*(C'\fR repre\*'sente tous les caracte\*`res entre \*(L"a\*(R" et \*(L"z\*(R" inclus. Si vous voulez inclure dans la classe le caracte\*`re \*(L"\-\*(R" ou \*(L"]\*(R" lui\-me\*^me, mettez le au de\*'but de la classe (apre\*`s un e\*'ventuel \*(L"^\*(R") ou pre\*'fixez le par un \*(L"\e\*(R". \*(L"\-\*(R" est aussi interpre\*'te\*' litte\*'ralement si il est place\*' en fin de classe, juste avant le \*(L"]\*(R". (Les exemples suivants de\*'crivent tous la me\*^me classe de trois caracte\*`res: \f(CW\*(C`[\-az]\*(C'\fR, \&\f(CW\*(C`[az\-]\*(C'\fR, \f(CW\*(C`[a\e\-z]\*(C'\fR. Ils sont tous diffe\*'rents de \f(CW\*(C`[a\-z]\*(C'\fR qui de\*'crit une classe contenant 26 caracte\*`res.) Notez que si vous essayez d'utiliser \f(CW\*(C`\ew\*(C'\fR, \&\f(CW\*(C`\eW\*(C'\fR, \f(CW\*(C`\es\*(C'\fR, \f(CW\*(C`\eS\*(C'\fR, \f(CW\*(C`\ed\*(C'\fR ou \f(CW\*(C`\eD\*(C'\fR comme borne d'un intervalle, ce ne sera pas un intervalle et le \*(L"\-\*(R" sera interpre\*'te\*' litte\*'ralement. .PP Remarquez aussi que le concept de classe de caracte\*`res n'est pas vraiment portable entre diffe\*'rents codages \*(-- et me\*^me dans un me\*^me codage, cela peut produire un re\*'sultat que vous n'attendez pas. Un bon principe de base est de n'utiliser que des intervalles qui commencent et se terminent dans le me\*^me alphabet ([a\-e], [A\-E]) ou dans les chiffres ([0\-9]). Tout le reste n'est pas su\*^r. Dans le doute, e\*'nume\*'rez l'ensemble des caracte\*`res explicitement. .PP Certains caracte\*`res peuvent e\*^tre spe\*'cifie\*'s avec la syntaxe des me\*'ta\-caracte\*`res comme en C\ : \*(L"\en\*(R" reconnai\*^t le caracte\*`re nouvelle ligne, \*(L"\et\*(R" reconnai\*^t une tabulation, \*(L"\er\*(R" reconnai\*^t un retour chariot, \*(L"\ef\*(R" reconnai\*^t un changement de page, etc. Plus ge\*'ne\*'ralement, \e\fInnn\fR, ou\*` \fInnn\fR est une suite de chiffres en octaux, reconnai\*^t le caracte\*`re dont le code \s-1ASCII\s0 est \fInnn\fR. De me\*^me, \&\ex\fInn\fR, ou\*` \fInn\fR est une suite de chiffres hexade\*'cimaux, reconnai\*^t le caracte\*`re dont le code \s-1ASCII\s0 est \fInn\fR. L'expression \ec\fIx\fR reconnai\*^t le caracte\*`re \s-1ASCII\s0 control\-\fIx\fR. Pour terminer, le me\*'ta\-caracte\*`re \*(L".\*(R" reconnai\*^t n'importe quel caracte\*`re sauf \*(L"\en\*(R" (a\*` moins d'utiliser \f(CW\*(C`/s\*(C'\fR). .PP Vous pouvez de\*'crire une se\*'rie de choix dans un motif en les se\*'parant par des \&\*(L"|\*(R". Donc \f(CW\*(C`fee|fie|foe\*(C'\fR reconnai\*^tra n'importe quel \*(L"fee\*(R", \*(L"fie\*(R" ou \*(L"foe\*(R" dans la chai\*^ne a\*` analyser (comme le ferait \f(CW\*(C`f(e|i|o)e\*(C'\fR). Le premier choix inclut tout ce qui suit le pre\*'ce\*'dent de\*'limiteur de motif (\*(L"(\*(R", \*(L"[\*(R" ou le de\*'but du motif) jusqu'au premier \*(L"|\*(R" et le dernier choix inclut tout ce qui suit le dernier \*(L"|\*(R" jusqu'au prochain de\*'limiteur de motif. C'est pour cette raison qu'il est courant d'entourer les choix entre parenthe\*`ses pour minimiser les risques de mauvaises interpre\*'tation de de\*'but et de fin. .PP Les diffe\*'rents choix sont essaye\*'s de la gauche vers la droite et le premier choix qui autorise la reconnaissance de l'ensemble du motif est retenu. Ce qui signifie que les choix ne sont pas obligatoirement \*(L"gourmand\*(R". Par exemple: en appliquant \f(CW\*(C`foo|foot\*(C'\fR a\*` \*(L"barefoot\*(R", seule la partie \*(L"foo\*(R" est reconnue puisque c'est le premier choix essaye\*' et qu'il permet la reconnaissance du motif complet. (Cela peu sembler anodin mais ne l'est pas lorsque vous me\*'morisez du texte gra\*^ce aux parenthe\*`ses.) .PP Souvenez-vous aussi que \*(L"|\*(R" est interpre\*'te\*' litte\*'ralement lorsqu'il est pre\*'sent dans une classe de caracte\*`res. Donc si vous e\*'crivez \f(CW\*(C`[fee|fie|foe]\*(C'\fR, vous recherchez en fait \f(CW\*(C`[feio|]\*(C'\fR. .PP A\*` l'inte\*'rieur d'un motif, vous pouvez me\*'moriser ce que reconnai\*^t un sous-motif en l'entourant de parenthe\*`ses. Plus loin dans le motif, vous pouvez faire re\*'fe\*'rence au \fIn\fR\-ieme sous-motif me\*'morise\*' en utilisant le me\*'ta\-caracte\*`re \&\e\fIn\fR. Les sous-motifs sont nume\*'rote\*'s de droite a\*` gauche dans l'ordre de leurs parenthe\*`ses ouvrantes. Une re\*'fe\*'rence reconnai\*^t exactement la chai\*^ne actuellement reconnue par le sous-motif correspondant et non pas n'importe quelle chai\*^ne qu'il aurait pu reconnai\*^tre. Par conse\*'quent, \f(CW\*(C`(0|0x)\ed*\es\e1\ed*\*(C'\fR reconnai\*^tra \*(L"0x1234 0x4321\*(R" mais pas \*(L"0x1234 01234\*(R" car, me\*^me si \f(CW\*(C`(0|0x)\*(C'\fR peut reconnai\*^tre le 0 dans le second nombre, ce sous-motif reconnai\*^t dans ce cas \*(L"0x\*(R". .ie n .Sh "\s-1AVERTISSEMENT\s0 concernant \e1 et $1" .el .Sh "\s-1AVERTISSEMENT\s0 concernant \e1 et \f(CW$1\fP" .IX Subsection "AVERTISSEMENT concernant 1 et $1" Quelques personnes ont l'habitude d'e\*'crire des choses comme\ : .PP .Vb 1 \& $pattern =~ s/(\eW)/\e\e\e1/g; .Ve .PP Dans la partie droite d'une substitution, ce sont des vieilleries pour ne pas choquer les fanas de \f(CW\*(C`sed\*(C'\fR mais ce sont de mauvaises habitudes. Parce que du point du vue Perl, la partie droite d'un \f(CW\*(C`s///\*(C'\fR est conside\*'re\*'e comme une chai\*^ne entre guillemets. \f(CW\*(C`\e1\*(C'\fR dans une chai\*^ne entre guillemets signifie normalement control\-A. Le sens Unix habituel de \f(CW\*(C`\e1\*(C'\fR n'est repris que dans \&\f(CW\*(C`s///\*(C'\fR. Par contre, si vous prenez cette mauvaise habitude, vous serez tre\*`s perturbe\*' si vous ajoutez le modificateur \f(CW\*(C`/e\*(C'\fR\ : .PP .Vb 1 \& s/(\ed+)/ \e1 + 1 /eg; # provoque un "warning" avec \-w .Ve .PP ou si vous essayez\ : .PP .Vb 1 \& s/(\ed+)/\e1000/; .Ve .PP Vous ne pouvez lever l'ambigui\*:te\*' en e\*'crivant \f(CW\*(C`\e{1}000\*(C'\fR alors que c'est possible gra\*^ce a\*` \f(CW\*(C`${1}000\*(C'\fR. En fait, il ne faut pas confondre l'ope\*'ration d'interpolation et l'ope\*'ration de reconnaissance d'une re\*'fe\*'rence. Elles ont certainement deux sens bien diffe\*'rents dans la partie \fIgauche\fR de \f(CW\*(C`s///\*(C'\fR. .Sh "Re\*'pe\*'tition de motifs de reconnaissance de longueur nulle" .IX Subsection "Re'pe'tition de motifs de reconnaissance de longueur nulle" \&\s-1AVERTISSEMENT:\s0 ce qui suit est difficile. Cette section doit e\*^tre re\*'e\*'crite. .PP Les expressions rationnelles fournissent un langage de programmation laconique et puissant. Comme avec la plupart des autres outils puissants, ce pouvoir peut faire des ravages. .PP Un fre\*'quent \*(L"abus de pouvoir\*(R" de\*'coule de la possibilite\*' de cre\*'er des boucles sans fin avec des expressions rationnelles aussi innocentes que\ : .PP .Vb 1 \& 'foo' =~ m{ ( o? )* }x; .Ve .PP \&\f(CW\*(C`o?\*(C'\fR peut e\*^tre reconnu au de\*'but de \f(CW'foo'\fR et, puisque la position dans la chai\*^ne n'est pas modifie\*'e par la reconnaissance, \f(CW\*(C`o?\*(C'\fR sera reconnu inde\*'finiment a\*` cause du modificateur \f(CW\*(C`*\*(C'\fR. L'utilisation du modificateur \&\f(CW\*(C`//g\*(C'\fR est un autre moyen courant d'obtenir de telle cycle\ : .PP .Vb 1 \& @matches = ( 'foo' =~ m{ o? }xg ); .Ve .PP ou .PP .Vb 1 \& print "match: <$&>\en" while 'foo' =~ m{ o? }xg; .Ve .PP ou encore dans la boucle induite par \fIsplit()\fR. .PP Par contre, une longue expe\*'rience montre que de nombreuses ta\*^ches de programmation peuvent vraiment se simplifier gra\*^ce a\*` la reconnaissance re\*'pe\*'te\*'e de sous-expressions e\*'ventuellement de longueur nulle. En voici un exemple simple: .PP .Vb 2 \& @chars = split //, $string; # // n'est pas magique pour split \& ($whitewashed = $string) =~ s/()/ /g; # les parentheses supprime la magie de s// / .Ve .PP Donc Perl autorise la construction \f(CW\*(C`/()/\*(C'\fR qui \fIrompt de force la boucle infinie\fR. Les re\*`gles pour les boucles de bas niveau obtenues par les modificateurs gourmands \f(CW\*(C`*+{}\*(C'\fR sont diffe\*'rentes de celles de haut niveau induites par exemples par \f(CW\*(C`/g\*(C'\fR ou par l'ope\*'rateur \fIsplit()\fR. .PP Les boucles de bas niveau sont interrompues lorsqu'on de\*'tecte la re\*'pe\*'tition d'une expression reconnaissant une sous\-chai\*^ne de longueur nulle. Donc .PP .Vb 1 \& m{ (?: NON_ZERO_LENGTH | ZERO_LENGTH )* }x; .Ve .PP est en fait e\*'quivalent a\*` .PP .Vb 4 \& m{ (?: NON_ZERO_LENGTH )* \& | \& (?: ZERO_LENGTH )? \& }x; .Ve .PP Les boucles de haut niveau se souviennent entre les ite\*'rations que la dernie\*`re chai\*^ne reconnue e\*'tait de longueur nulle. Pour briser la boucle infinie, une chai\*^ne reconnue ne peut\-e\*^tre de longueur nulle si la pre\*'ce\*'dente l'e\*'tait. Cette interdiction interfe\*`re avec le retour arrie\*`re (voir \&\*(L"Retour arrie\*`re\*(R") et dans ce cas, la \fIseconde meilleure\fR chai\*^ne est choisie si la \fImeilleure\fR est de longueur nulle. .PP Par exemple\ : .PP .Vb 2 \& $_ = 'bar'; \& s/\ew??/<$&>/g; .Ve .PP produit \f(CW\*(C`<><><><>\*(C'\fR. A\*` chaque position dans la chai\*^ne, la meilleur chai\*^ne reconnue par le sobre \f(CW\*(C`??\*(C'\fR est la chai\*^ne de longueur nulle et la seconde meilleure chai\*^ne est celle reconnue par \f(CW\*(C`\ew\*(C'\fR. Donc les reconnaissances de longueur nulle alternent avec celles d'un caracte\*`re de long. .PP De manie\*`re similaire, pour des \f(CW\*(C`m/()/g\*(C'\fR re\*'pe\*'te\*'s, la seconde meilleure reconnaissance est un cran plus loin dans la chai\*^ne. .PP La me\*'morisation de l'e\*'tat \fIpre\*'ce\*'dente reconnaissance de longueur nulle\fR est lie\*'e a\*` chaque chai\*^ne explore\*'e. De plus, elle est re\*'initialise\*'e a\*` chaque affectation de \fIpos()\fR. Les reconnaissances de longueur nulle a\*` la fin de la pre\*'ce\*'dente reconnaissance sont ignore\*'es durant un \f(CW\*(C`split\*(C'\fR. .Sh "Combinaison d'expressions rationnelles" .IX Subsection "Combinaison d'expressions rationnelles" Dans une expression rationnelle, chaque composant e\*'le\*'mentaire tel que de\*'crit pre\*'ce\*'demment (comme \f(CW\*(C`ab\*(C'\fR ou \f(CW\*(C`\eZ\*(C'\fR) peut reconnai\*^tre au plus une sous\-chai\*^ne a\*` une position donne\*'e de la chai\*^ne examine\*'e. Par contre, dans une expression rationnelle typique, ces composants e\*'le\*'mentaires sont combine\*'s entre eux pour faire des expressions rationnelles plus complexes en utilisant les ope\*'rateurs de combinaison \f(CW\*(C`ST\*(C'\fR, \f(CW\*(C`S|T\*(C'\fR, \f(CW\*(C`S*\*(C'\fR, etc. (dans ces exemples \f(CW\*(C`S\*(C'\fR et \f(CW\*(C`T\*(C'\fR sont des expressions rationnelles). .PP De telles combinaisons peuvent inclure des alternatives, amenant ainsi a\*` un proble\*`me de choix\ : lorsqu'on applique l'expression rationnelle \f(CW\*(C`a|ab\*(C'\fR a\*` la chai\*^ne \f(CW"abc"\fR, est-ce \f(CW"a"\fR ou \f(CW"ab"\fR qui est reconnu\ ? Un moyen de de\*'crire le choix effectue\*' passe par le concept de retour arrie\*`re (voir \&\*(L"Retour arrie\*`re\*(R"). Par contre, cette description est de trop bas niveau et vous ame\*`ne a\*` penser en termes d'une imple\*'mentation particulie\*`re. .PP Une autre manie\*`re de de\*'crire les choses commence par les notions de \&\*(L"meilleur\*(R"/\*(L"pire\*(R". Toutes les sous\-chai\*^nes qui peuvent e\*^tre reconnues par une expression rationnelle sont trie\*'es de la \*(L"meilleure\*(R" a\*` la \*(L"pire\*(R" et c'est la meilleure qui est choisie. Cela remplace la question \*(L"Qu'est\-ce qui est choisi\ ?\*(R" par la question \*(L"Quelle la meilleure reconnaissance et quelle est la pire\ ?\*(R". .PP Pour la plupart des morceaux e\*'le\*'mentaires, la question ne se pose pas puisqu'au plus une sous\-chai\*^ne peut e\*^tre reconnue a\*` un emplacement donne\*'. Cette section de\*'crit la notion de meilleure/pire pour les ope\*'rateurs de combinaison. Dans les descriptions ci\-dessous, \f(CW\*(C`S\*(C'\fR et \f(CW\*(C`T\*(C'\fR de\*'signent des sous-expressions rationnelles. .ie n .IP """ST""" 4 .el .IP "\f(CWST\fR" 4 .IX Item "ST" Soit deux correspondances possibles\ : \f(CW\*(C`AB\*(C'\fR et \f(CW\*(C`A'B'\*(C'\fR. \f(CW\*(C`A\*(C'\fR et \f(CW\*(C`A'\*(C'\fR sont deux sous\-chai\*^nes qui peuvent e\*^tre reconnues par \f(CW\*(C`S\*(C'\fR. \f(CW\*(C`B\*(C'\fR et \f(CW\*(C`B'\*(C'\fR sont deux sous\-chai\*^nes qui peuvent e\*^tre reconnues par \f(CW\*(C`T\*(C'\fR. .Sp Si \f(CW\*(C`A\*(C'\fR est une meilleure correspondance pour \f(CW\*(C`S\*(C'\fR que \f(CW\*(C`A'\*(C'\fR alors \f(CW\*(C`AB\*(C'\fR est une meilleure correspondance pour \f(CW\*(C`ST\*(C'\fR que \f(CW\*(C`A'B'\*(C'\fR. .Sp Si \f(CW\*(C`A\*(C'\fR et \f(CW\*(C`A'\*(C'\fR sont similaires alors \f(CW\*(C`AB\*(C'\fR est une meilleure correspondance pour \f(CW\*(C`ST\*(C'\fR que \f(CW\*(C`A'B'\*(C'\fR si \f(CW\*(C`B\*(C'\fR est une meilleure correspondance pour \f(CW\*(C`T\*(C'\fR que \&\f(CW\*(C`B'\*(C'\fR. .ie n .IP """S|T""" 4 .el .IP "\f(CWS|T\fR" 4 .IX Item "S|T" Lorsque \f(CW\*(C`S\*(C'\fR peut e\*^tre reconnu, c'est une meilleure correspondance qui si seul \&\f(CW\*(C`T\*(C'\fR peut correspondre. .Sp L'ordre entre deux correspondances pour \f(CW\*(C`S\*(C'\fR est le me\*^me que pour \f(CW\*(C`S\*(C'\fR seul. Et c'est la me\*^me chose pour deux correspondances pour \f(CW\*(C`T\*(C'\fR. .ie n .IP """S{COMPTEUR}""" 4 .el .IP "\f(CWS{COMPTEUR}\fR" 4 .IX Item "S{COMPTEUR}" Correspond a\*` \f(CW\*(C`SSS...S\*(C'\fR (re\*'pe\*'te\*' autant que ne\*'cessaire). .ie n .IP """S{min,max}""" 4 .el .IP "\f(CWS{min,max}\fR" 4 .IX Item "S{min,max}" Correspond a\*` \f(CW\*(C`S{max}|S{max\-1}|...|S{min+1}|S{min}\*(C'\fR. .ie n .IP """S?""\fR, \f(CW""S*""\fR, \f(CW""S+""" 4 .el .IP "\f(CWS?\fR, \f(CWS*\fR, \f(CWS+\fR" 4 .IX Item "S?, S*, S+" Pareil que \f(CW\*(C`S{0,1}\*(C'\fR, \f(CW\*(C`S{0,INFINI}\*(C'\fR et \f(CW\*(C`S{1,INFINI}\*(C'\fR respectivement. .ie n .IP """S??""\fR, \f(CW""S*?""\fR, \f(CW""S+?""" 4 .el .IP "\f(CWS??\fR, \f(CWS*?\fR, \f(CWS+?\fR" 4 .IX Item "S??, S*?, S+?" Pareil que \f(CW\*(C`S{0,1}?\*(C'\fR, \f(CW\*(C`S{0,INFINI}?\*(C'\fR et \f(CW\*(C`S{1,INFINI}?\*(C'\fR respectivement. .ie n .IP """(?>S)""" 4 .el .IP "\f(CW(?>S)\fR" 4 .IX Item "(?>S)" Reconnait la meilleure correspondance pour \f(CW\*(C`S\*(C'\fR et uniquement celle\-la\*`. .ie n .IP """(?=S)""\fR, \f(CW""(?<=S)""" 4 .el .IP "\f(CW(?=S)\fR, \f(CW(?<=S)\fR" 4 .IX Item "(?=S), (?<=S)" Pour ces ope\*'rateurs, il n'est pas ne\*'cessaire de de\*'crire l'ordre puisque seul importe de savoir que \f(CW\*(C`S\*(C'\fR peut ou non e\*^tre reconnu. .ie n .IP """(??{ EXPR })""" 4 .el .IP "\f(CW(??{ EXPR })\fR" 4 .IX Item "(??{ EXPR })" L'ordre est le me\*^me que celui de l'expression rationnelle qui est le re\*'sultat de \s-1EXPR\s0. .ie n .IP """(?(condition)motif\-oui|motif\-non)""" 4 .el .IP "\f(CW(?(condition)motif\-oui|motif\-non)\fR" 4 .IX Item "(?(condition)motif-oui|motif-non)" Souvenez-vous que le choix du motif a\*` reconnai\*^tre (entre \f(CW\*(C`motif\-oui\*(C'\fR et \&\f(CW\*(C`motif\-non\*(C'\fR) est de\*'ja\*` fait. L'ordre des reconnaissances est le me\*^me que celui du motif retenu. .PP Les principes pre\*'ce\*'dents de\*'crivent l'ordre des reconnaissances \fIa\*` une position donne\*'e\fR. Une re\*`gle supple\*'mentaire est ne\*'cessaire pour comprendre comment est de\*'termine\*' la reconnaissance pour une expression rationnelle comple\*`te\ : une reconnaissance a\*` une position donne\*'e est toujours meilleure qu'une reconnaissance a\*` une position plus lointaine. .Sh "Cre\*'ation de moteurs \s-1RE\s0 spe\*'cifiques (customise\*'s)" .IX Subsection "Cre'ation de moteurs RE spe'cifiques (customise's)" La surcharge de constantes (voir overload) est un moyen simple d'augmenter les fonctionnalite\*'s du moteur \s-1RE\s0 (le moteur de reconnaissance d'expressions rationnelles). .PP Imaginons que vous voulez de\*'finir une nouvelle se\*'quence \f(CW\*(C`\eY|\*(C'\fR qui peut e\*^tre reconnue a\*` la limite entre un espace et un autre caracte\*`re. Remarquez que \&\f(CW\*(C`(?=\eS)(? \e&convert; \& } \& \& sub invalid { die "/$_[0]/: invalid escape '\e\e$_[1]'"} \& \& my %rules = ( '\e\e' => '\e\e', \& 'Y|' => qr/(?=\eS)(?; \& chomp $re; \& $re = customre::convert $re; \& /\eY|$re\eY|/; .Ve .SH "BUGS" .IX Header "BUGS" Le niveau de ce document varie de \*(L"difficile a\*` comprendre\*(R" jusqu'a\*` \*(L"totalement opaque\*(R". La prose divaguante et crible\*'e de jargon est difficile a\*` interpre\*'ter en divers endroits. .SH "VOIR AUSSI" .IX Header "VOIR AUSSI" \&\*(L"Ope\*'rateurs d'expression rationnelle\*(R" in perlop. .PP \&\*(L"Les de\*'tails sordides de l'interpre\*'tation des chai\*^nes\*(R" in perlop. .PP perlfaq6. .PP \&\*(L"pos\*(R" in perlfunc. .PP perllocale. .PP perlebcdic. .PP \&\fIMastering Regular Expressions\fR par Jeffrey Friedl, publie\*' chez O'Reilly and Associates. .SH "TRADUCTION" .IX Header "TRADUCTION" .Sh "Version" .IX Subsection "Version" Cette traduction franc\*,aise correspond a\*` la version anglaise distribue\*'e avec perl 5.6.1. Pour en savoir plus concernant ces traductions, consultez . .Sh "Traducteur" .IX Subsection "Traducteur" Traduction initiale et mise a\*` jour 5.6.0 puis 5.6.1\ : Paul Gaborit .Sh "Relecture" .IX Subsection "Relecture" Re\*'gis Julie\*'