mirror of
https://github.com/php/doc-fr.git
synced 2026-03-24 07:02:06 +01:00
2648 lines
101 KiB
XML
2648 lines
101 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- EN-Revision: a0434e05111acabf2b9b2c7847e7e733f8dab0dc Maintainer: yannick Status: ready -->
|
||
<!-- Reviewed: no -->
|
||
|
||
<chapter xml:id="reference.pcre.pattern.syntax" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||
<title>Syntaxe des masques</title>
|
||
<titleabbrev>Fonctionnement des expressions régulières</titleabbrev>
|
||
|
||
<section xml:id="regexp.introduction">
|
||
&reftitle.intro;
|
||
<para>
|
||
La syntaxe et la sémantique des expressions régulières
|
||
supportées par PCRE sont décrites dans cette section. 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.
|
||
Le livre de Jeffrey Friedl "Mastering Regular Expressions", édité
|
||
chez O'Reilly (ISBN 1-56592-257-3), les décrit en profondeur.
|
||
Cette description est organisée comme une documentation de
|
||
référence.
|
||
</para>
|
||
<para>
|
||
Une expression rationnelle est un masque appliqué à
|
||
une chaîne sujet, de gauche à droite. La plupart des
|
||
caractères se représentent eux-mêmes. Un exemple
|
||
trivial : un masque qui serait "<literal>Le rapide renard gris</literal>",
|
||
pourra correspondre à une partie de la chaîne sujet qui sera
|
||
identique au masque, par exemple
|
||
"<literal>Le rapide renard gris court dans la forêt</literal>",
|
||
</para>
|
||
</section>
|
||
<section xml:id="regexp.reference.delimiters">
|
||
<title>Délimiteurs</title>
|
||
<para>
|
||
Lors de l'utilisation des fonctions PCRE, il est nécessaire que le motif soit encadré
|
||
par des <emphasis>délimiteurs</emphasis>. Un délimiteur peut être n'importe quel caractère
|
||
non alpha-numérique autre qu'un backslash ou qu'un espace.
|
||
Les caractères d'espacement blanc avant un délimiteur valide sont silencieusement ignorés.
|
||
</para>
|
||
<para>
|
||
Les délimiteurs les plus courants sont les slashes (<literal>/</literal>), dièses
|
||
(<literal>#</literal>) et les tildes (<literal>~</literal>). Les exemples suivants ont
|
||
tous des motifs encadrés avec des délimiteurs valides.
|
||
<informalexample>
|
||
<programlisting>
|
||
<![CDATA[
|
||
/foo bar/
|
||
#^[^0-9]$#
|
||
+php+
|
||
%[a-zA-Z0-9_-]%
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
<para>
|
||
Il est également possible d'utiliser les délimiteurs utilisant les crochets
|
||
où les crochets ouvrants et fermants sont respectivement les délimiteurs de
|
||
début et de fin. <literal>()</literal>, <literal>{}</literal>,
|
||
<literal>[]</literal> et <literal><></literal> sont tous des styles
|
||
de crochets valides.
|
||
<informalexample>
|
||
<programlisting>
|
||
<![CDATA[
|
||
(this [is] a (pattern))
|
||
{this [is] a (pattern)}
|
||
[this [is] a (pattern)]
|
||
<this [is] a (pattern)>
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
Les délimiteurs utilisant les crochets n'ont pas besoin d'être échappés lorsqu'ils
|
||
sont utilisés comme caractères méta dans un masque, mais, comme tout autre opérateur,
|
||
ils doivent être échappés s'ils sont utilisés comme caractères littéraux.
|
||
</para>
|
||
<para>
|
||
Si le délimiteur doit être décrit dans le motif, il doit être échappé avec un backslash.
|
||
Si le délimiteur apparait souvent dans le motif, choisir un autre délimiteur est une bonne
|
||
idée pour en augmenter la lisibilité.
|
||
<informalexample>
|
||
<programlisting>
|
||
<![CDATA[
|
||
/http:\/\//
|
||
#http://#
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
La fonction <function>preg_quote</function> peut être utilisée pour échapper une chaîne
|
||
et l'utiliser dans un motif. Son second paramètre optionnel sert à spécifier le délimiteur
|
||
qui doit être échappé.
|
||
</para>
|
||
<para>
|
||
Il est aussi possible d'utiliser des <link linkend="reference.pcre.pattern.modifiers">
|
||
modificateurs de motif</link> après le délimiteur final. L'exemple suivant montre
|
||
une correspondance insensible à la casse.
|
||
<informalexample>
|
||
<programlisting>
|
||
<![CDATA[
|
||
#[a-z]#i
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
</para>
|
||
</section>
|
||
<section xml:id="regexp.reference.meta">
|
||
<title>Métacaractères</title>
|
||
<para>
|
||
La puissance des expressions régulières provient de
|
||
leur capacité à autoriser des alternatives et des quantificateurs
|
||
de répétition dans le masque. Ils sont encodés
|
||
dans le masque par des <emphasis>métacaractères</emphasis>, qui ne représentent
|
||
pas ce qu'ils sont, mais sont interprétés d'une certaine
|
||
manière.
|
||
</para>
|
||
<para>
|
||
Il y a deux sortes de métacaractères : ceux qui sont
|
||
reconnus n'importe où dans un masque, hormis entre crochets,
|
||
et ceux qui sont reconnus entre crochets.
|
||
À l'extérieur des crochets, les métacaractères sont :
|
||
|
||
<table>
|
||
<title>Métacaractère en dehors des crochets</title>
|
||
<tgroup cols="2">
|
||
<thead>
|
||
<row>
|
||
<entry>Métacaractère</entry><entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>\</entry><entry>Caractère d'échappement, avec de multiples usages</entry>
|
||
</row>
|
||
<row>
|
||
<entry>^</entry><entry>Le début de la chaîne sujet (ou de ligne, en mode multilignes)</entry>
|
||
</row>
|
||
<row>
|
||
<entry>$</entry><entry>La fin de la chaîne sujet ou
|
||
avant la fin d'une nouvelle ligne (ou fin de ligne, en mode multilignes)</entry>
|
||
</row>
|
||
<row>
|
||
<entry>.</entry><entry>Remplace n'importe quel caractère, hormis le caractère de nouvelle ligne (par défaut)</entry>
|
||
</row>
|
||
<row>
|
||
<entry>[</entry><entry>Caractère de début de définition de classe</entry>
|
||
</row>
|
||
<row>
|
||
<entry>]</entry><entry>Caractère de fin de définition de classe</entry>
|
||
</row>
|
||
<row>
|
||
<entry>|</entry><entry>Caractère de début d'alternative</entry>
|
||
</row>
|
||
<row>
|
||
<entry>(</entry><entry>Caractère de début de sous-masque</entry>
|
||
</row>
|
||
<row>
|
||
<entry>)</entry><entry>Caractère de fin de sous-masque</entry>
|
||
</row>
|
||
<row>
|
||
<entry>?</entry><entry>Étend le sens de (; quantificateur de 0 ou 1; quantificateur de minimisation
|
||
(Voir les <link linkend="regexp.reference.repetition">répétitions</link>)</entry>
|
||
</row>
|
||
<row>
|
||
<entry>*</entry><entry>Quantificateur de 0 ou plus</entry>
|
||
</row>
|
||
<row>
|
||
<entry>+</entry><entry>Quantificateur de 1 ou plus</entry>
|
||
</row>
|
||
<row>
|
||
<entry>{</entry><entry>Caractère de début de quantificateur minimum/maximum</entry>
|
||
</row>
|
||
<row>
|
||
<entry>}</entry><entry>Caractère de fin de quantificateur minimum/maximum</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
|
||
La partie du masque qui est entourée de crochets est appelée
|
||
classe de caractères. Dans
|
||
<link linkend="regexp.reference.character-classes">les classes de caractères</link>,
|
||
les seuls métacaractères autorisés sont :
|
||
|
||
<table>
|
||
<title>Meta-characters dans des crochets (<emphasis>classes de caractères</emphasis>)</title>
|
||
<tgroup cols="2">
|
||
<thead>
|
||
<row>
|
||
<entry>Métacaractère</entry><entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>\</entry><entry>Caractère de protection, avec de multiples usages</entry>
|
||
</row>
|
||
<row>
|
||
<entry>^</entry><entry>Négation de la classe, mais uniquement si placé tout au début de la classe</entry>
|
||
</row>
|
||
<row>
|
||
<entry>-</entry><entry>Indique un intervalle de caractères</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
|
||
La section suivante décrit l'utilisation de chaque
|
||
métacaractère.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.escape">
|
||
<title>Séquences d'échappement</title>
|
||
<para>
|
||
Le caractère antislash a de nombreuses utilisations.
|
||
En premier lieu, s'il est suivi d'un caractère non
|
||
alphanumérique, il ne prendra pas la signification
|
||
spéciale qui y est rattachée. Cette utilisation de
|
||
l'antislash comme caractère de protection s'applique
|
||
à l'intérieur et à l'extérieur des
|
||
classes de caractères.
|
||
</para>
|
||
<para>
|
||
Par exemple, pour rechercher le
|
||
caractère étoile "<literal>*</literal>", il faut
|
||
écrire dans le masque : "<literal>\*</literal>". Cela
|
||
s'applique dans tous les cas, que le caractère qui suive
|
||
soit un métacaractère ou non. C'est un moyen sûr
|
||
pour s'assurer qu'un caractère sera recherché
|
||
pour sa valeur littérale, plutôt que pour sa valeur
|
||
spéciale. En particulier, pour rechercher les antislashs,
|
||
il faut écrire : "<literal>\\</literal>".
|
||
</para>
|
||
<note>
|
||
<para>
|
||
La <link linkend="language.types.string.syntax">chaîne de caractères</link> PHP
|
||
simple ou double guillemet a une signification spéciale des antislashs. Donc,
|
||
si \ doit être recherché avec une expression rationnelle \\, alors
|
||
"\\\\" ou '\\\\' doit être utilisé dans le code PHP.
|
||
</para>
|
||
</note>
|
||
<para>
|
||
Si un masque est utilisé avec l'option
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_EXTENDED</link>,
|
||
les espaces blancs du masque, mais qui ne sont pas dans une
|
||
classe de caractères et les caractères entre dièse
|
||
"<literal>#</literal>", ainsi que les nouvelles lignes sont ignorées.
|
||
L'antislash peut être utilisé pour les protéger et ainsi
|
||
rechercher un espace ou un dièse.
|
||
</para>
|
||
<para>
|
||
La deuxième utilité de l'antislash 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'elles représentent :
|
||
</para>
|
||
<para>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term><emphasis>\a</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
alarme, c'est-à-dire le caractère BEL (hex 07)
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\cx</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
"contrôle-x", avec x qui peut être n'importe quel
|
||
caractère.
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\e</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
escape (hex 1B)
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\f</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
formfeed (hex 0C)
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\n</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
nouvelle ligne (hex 0A)
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\p{xx}</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
un caractère avec une propriété xx, voir
|
||
les <link linkend="regexp.reference.unicode">propriétés unicode</link>
|
||
pour plus d'informations
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\P{xx}</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
un caractère sans propriété xx, voir
|
||
les <link linkend="regexp.reference.unicode">propriétés unicode</link>
|
||
pour plus d'informations
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\r</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
retour chariot (hex 0D)
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\R</emphasis></term>
|
||
<listitem>
|
||
<simpara>saut de ligne : satisfait par \n, \r et \r\n</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\t</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
tabulation (hex 09)
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\xhh</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
caractère en hexadécimal, de code hh
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\ddd</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
caractère en octal, de code ddd, ou référence
|
||
arrière
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</para>
|
||
<para>
|
||
Dans la séquence "<literal>\cx</literal>" si "<literal>x</literal>"
|
||
est en minuscule, il est converti en majuscule. Puis, le bit 6 (hex 40)
|
||
est inversé. Ainsi "<literal>\cz</literal>" devient hex 1A,
|
||
mais "<literal>\c{</literal>" devient hex 3B, tandis que "<literal>\c;</literal>"
|
||
devient hex 7B.
|
||
</para>
|
||
<para>
|
||
Après "<literal>\x</literal>", deux caractères
|
||
hexadécimaux sont lus (les lettres peuvent être en majuscule
|
||
ou minuscule).
|
||
En mode <emphasis>UTF-8</emphasis>, "<literal>\x{...}</literal>"
|
||
est autorisée, où le contenu des accolades est une chaîne hexadécimale.
|
||
Il sera interprété comme un caractère UTF-8 où le numéro de code est
|
||
le numéro hexadécimal donné. La séquence d'échappement hexadécimale
|
||
originale, <literal>\xhh</literal>, correspond à un caractère UTF-8
|
||
sur 2 octets si la valeur est plus grande que 127.
|
||
</para>
|
||
<para>
|
||
Après "<literal>\0</literal>", deux caractères octaux sont lus.
|
||
Dans chacun des cas, le métacaractère tente de lire autant
|
||
de caractères que possible. Ainsi, la séquence
|
||
"<literal>\0\x\07</literal>" sera comprise comme deux caractères nuls,
|
||
suivis d'un caractère alarme (BEL). Il faut s'assurer que l'on fournit
|
||
suffisamment de chiffres après le métacaractère.
|
||
</para>
|
||
<para>
|
||
L'antislash de fin suivi par un nombre autre que 0 est compliqué.
|
||
À l'extérieur d'une classe de caractère, PCRE le lit, et tous les nombres
|
||
qui suivent, en tant que nombres décimaux. Si le nombre est plus petit que
|
||
10 ou s'il y a eu au moins précédemment une parenthèse gauche capturante
|
||
dans l'expression, la séquence entière est prise en tant que <emphasis>référence arrière</emphasis>.
|
||
Une description sur le fonctionnement est donnée plus tard, suivez la discussion
|
||
sur les parenthèses des sous masques.
|
||
</para>
|
||
<para>
|
||
À l'intérieur d'un caractère de classe ou s'il est plus
|
||
grand que 9, et qu'il n'y a pas eu assez de parenthèses ouvrantes
|
||
auparavant, PCRE lit jusqu'à 3 chiffres octaux à la suite
|
||
de l'antislash, 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 représentent
|
||
eux-mêmes. Par exemple:
|
||
</para>
|
||
<para>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term><emphasis>\040</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
une autre manière d'écrire un espace
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\40</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
identique, dans la mesure où il n'y a pas 40
|
||
parenthèses ouvrantes auparavant
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\7</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
est toujours une référence arrière
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\11</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
peut être une référence de retour,
|
||
ou une tabulation
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\011</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
toujours une tabulation
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\0113</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
est une tabulation suivie du caractère "3"
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\113</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
est le caractère 113 (étant donné qu'il ne
|
||
peut y avoir plus de 99 références arrière)
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\377</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
est un octet dont tous les bits sont à 1
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\81</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
peut être soit une référence arrière,
|
||
soit un zéro binaire suivi des caractères "8" et "1"
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</para>
|
||
<para>
|
||
Les valeurs octales supérieures ou égales à 100 ne
|
||
doivent pas être introduites par un 0, car seuls les trois premiers
|
||
octets seront lus.
|
||
</para>
|
||
<para>
|
||
Toutes les séquences qui définissent une valeur d'un seul
|
||
octet peuvent être utilisées dans les classes de caractères,
|
||
et à l'extérieur. De plus, dans une classe de caractères,
|
||
la séquence "<literal>\b</literal>" est interprétée
|
||
comme un caractère effacer (hex 08). À l'extérieur,
|
||
elle peut avoir d'autres significations
|
||
(voir ci-dessous).
|
||
</para>
|
||
<para>
|
||
On peut encore se servir de l'antislash pour préciser des types
|
||
génériques de valeurs :
|
||
</para>
|
||
<para>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term><emphasis>\d</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
tout caractère décimal
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\D</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
tout caractère qui n'est pas un caractère décimal
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\h</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
n'importe quel espace horizontal
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\H</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
n'importe quel caractère qui n'est pas un espace horizontal
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\s</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
tout caractère blanc
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\S</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
tout caractère qui n'est pas un caractère blanc
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\v</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
n'importe quel espace vertical
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\V</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
n'importe quel caractère qui n'est pas un espace vertical
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\w</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
tout caractère de "mot"
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\W</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
tout caractère qui n'est pas un caractère de "mot"
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</para>
|
||
<para>
|
||
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étacaractère,
|
||
soit l'autre.
|
||
</para>
|
||
<para>
|
||
Les caractères "blancs" sont HT (9), LF (10), FF (12), CR (13),
|
||
et espace (32). Cependant, lors de l'utilisation d'une locale
|
||
particulière, tous les caractères se trouvant dans l'intervalle
|
||
128-255 peuvent aussi être considérés comme caractère blanc, par exemple
|
||
NBSP (A0).
|
||
</para>
|
||
<para>
|
||
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 <emphasis>mot</emphasis> 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ères. 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étacaractère <literal>\w</literal>.
|
||
</para>
|
||
<para>
|
||
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
|
||
placée en fin de masque, et qu'il n'y a plus de caractère à
|
||
comparer dans la chaîne sujet, la recherche échoue.
|
||
</para>
|
||
<para>
|
||
La quatrième utilisation de l'antislash 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écrite
|
||
plus bas. Les assertions avec antislash sont les suivantes :
|
||
</para>
|
||
<para>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term><emphasis>\b</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
limite de mot
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\B</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
pas limite de mot
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\A</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
début de la chaîne sujet
|
||
(indépendant du mode multilignes)
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\Z</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
fin de la chaîne sujet ou nouvelle ligne à
|
||
la fin de la chaîne sujet
|
||
(indépendant du mode multilignes)
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\G</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
position de la première occurrence trouvée dans la chaîne sujet
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\z</emphasis></term>
|
||
<listitem>
|
||
<simpara>
|
||
fin de la chaîne sujet
|
||
(indépendant du mode multilignes)
|
||
</simpara>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</para>
|
||
<para>
|
||
Ces assertions ne peuvent pas apparaître dans une classe de
|
||
caractères (mais "<literal>\b</literal>" a une autre signification à
|
||
l'intérieur d'une classe de caractères).
|
||
</para>
|
||
<para>
|
||
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 (<literal>\w</literal>), ou le contraire (<literal>\W</literal>)
|
||
(on peut le voir comme <literal>\w\W</literal> ou <literal>\W\w</literal>), ou encore le
|
||
premier ou le dernier caractère est un caractère mot (<literal>\w</literal>).
|
||
</para>
|
||
<para>
|
||
Les assertions <literal>\A</literal>, <literal>\Z</literal>, et
|
||
<literal>\z</literal> diffèrent des métacaractères
|
||
<literal>^</literal> et <literal>$</literal>
|
||
(décrit dans <link linkend="regexp.reference.anchors">les ancres</link>)
|
||
dans la mesure où ils ne sont pas dépendants des options, notamment
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link>
|
||
ou <link linkend="reference.pcre.pattern.modifiers">PCRE_DOLLAR_ENDONLY</link>.
|
||
La différence entre <literal>\Z</literal> et
|
||
<literal>\z</literal> tient au fait que <literal>\Z</literal> recherche
|
||
les positions avant les nouvelles lignes et à la fin de la
|
||
chaîne sujet, tandis que <literal>\z</literal> ne recherche
|
||
que la fin de la chaîne.
|
||
</para>
|
||
<para>
|
||
L'assertion <literal>\G</literal> est réalisée uniquement lorsque
|
||
la position courante de l'occurrence trouvée est au début de l'occurrence,
|
||
comme spécifié par l'argument <parameter>offset</parameter> de la
|
||
fonction <function>preg_match</function>. Elle diffère de <literal>\A</literal>
|
||
lorsque la valeur du paramètre <parameter>offset</parameter> est différente
|
||
de zéro.
|
||
</para>
|
||
<para>
|
||
<literal>\Q</literal> et <literal>\E</literal> peuvent être utilisés
|
||
pour ignorer les métacaractères dans le masque.
|
||
Par exemple : <literal>\w+\Q.$.\E$</literal> recherchera un ou plusieurs
|
||
caractères suivis par la chaîne littérale <literal>.$.</literal> et ancrés à la
|
||
fin de la chaîne.
|
||
Il est à noter que ceci ne change pas le comportement des délimiteurs ;
|
||
par exemple le masque <literal>#\Q#\E#$</literal> n'est pas valide, car
|
||
le second <literal>#</literal> marque la fin du masque, et que
|
||
<literal>\E#</literal> est interprété comme un modificateur invalide.
|
||
</para>
|
||
<para>
|
||
<literal>\K</literal> peut être utilisé pour réinitialiser le résultat
|
||
Par exemple, le masque <literal>foo\Kbar</literal> trouve
|
||
"foobar", mais reporte qu'il a trouvé "bar". L'utilisation de
|
||
<literal>\K</literal> n'interfère pas avec la configuration des sous-chaînes capturantes.
|
||
Par exemple, lorsque le masque <literal>(foo)\Kbar</literal>
|
||
trouve "foobar", la première sous-chaîne sera toujours "foo".
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.unicode">
|
||
<title>Propriétés des caractères Unicode</title>
|
||
<para>
|
||
Trois nouvelles séquences d'échappement
|
||
pour trouver des types de caractères sont disponibles lorsque
|
||
le mode <emphasis>UTF-8</emphasis> est sélectionné. Elles sont :
|
||
</para>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term><emphasis>\p{xx}</emphasis></term>
|
||
<listitem><simpara>un caractère avec les propriétés xx</simpara></listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\P{xx}</emphasis></term>
|
||
<listitem><simpara>un caractère sans les propriétés xx</simpara></listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term><emphasis>\X</emphasis></term>
|
||
<listitem><simpara>une séquence étendue Unicode</simpara></listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
<para>
|
||
Les noms des propriétés représentés par <literal>xx</literal> ci-dessus
|
||
sont limités aux catégories de propriétés générales Unicode. Chaque caractère
|
||
a exactement une seule de ces propriétés, spécifiée par une abréviation sur deux caractères.
|
||
Pour des raisons de compatibilité avec Perl, la négation peut être spécifiée
|
||
en incluant un accent circonflexe entre l'accolade ouvrante et le nom de la
|
||
propriété. Par exemple, <literal>\p{^Lu}</literal> équivaut à la même chose que
|
||
<literal>\P{Lu}</literal>.
|
||
</para>
|
||
<para>
|
||
Si une seule lettre est spécifiée avec <literal>\p</literal> ou <literal>\P</literal>,
|
||
il inclut toutes les propriétés qui commencent par cette lettre. Dans ce cas,
|
||
en l'absence de négation, les accolades dans la séquence d'échappement sont
|
||
optionnelles ; ceci revient à la même chose :
|
||
</para>
|
||
<informalexample>
|
||
<programlisting>
|
||
<![CDATA[
|
||
\p{L}
|
||
\pL
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
<table>
|
||
<title>Codes des propriétés supportées</title>
|
||
<tgroup cols="3">
|
||
<thead>
|
||
<row>
|
||
<entry>Propriétés</entry>
|
||
<entry>Correspondance</entry>
|
||
<entry>Notes</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry><literal>C</literal></entry>
|
||
<entry>Autre</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Cc</literal></entry>
|
||
<entry>Contrôle</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Cf</literal></entry>
|
||
<entry>Format</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Cn</literal></entry>
|
||
<entry>Non affecté</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Co</literal></entry>
|
||
<entry>Utilisation privée</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row rowsep="1">
|
||
<entry><literal>Cs</literal></entry>
|
||
<entry>Substitut</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>L</literal></entry>
|
||
<entry>Lettre</entry>
|
||
<entry>
|
||
Inclut les propriétés suivantes : <literal>Ll</literal>,
|
||
<literal>Lm</literal>, <literal>Lo</literal>, <literal>Lt</literal> et
|
||
<literal>Lu</literal>.
|
||
</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Ll</literal></entry>
|
||
<entry>Lettre en minuscule</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Lm</literal></entry>
|
||
<entry>Lettre de modification</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Lo</literal></entry>
|
||
<entry>Autres lettres</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Lt</literal></entry>
|
||
<entry>Lettre titrée</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row rowsep="1">
|
||
<entry><literal>Lu</literal></entry>
|
||
<entry>Lettre en majuscule</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>M</literal></entry>
|
||
<entry>Marque</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Mc</literal></entry>
|
||
<entry>Marque d'espacement</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Me</literal></entry>
|
||
<entry>Marque d'enfermement</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row rowsep="1">
|
||
<entry><literal>Mn</literal></entry>
|
||
<entry>Marque non espacée</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>N</literal></entry>
|
||
<entry>Nombre</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Nd</literal></entry>
|
||
<entry>Nombre décimal</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Nl</literal></entry>
|
||
<entry>Nombre Lettre</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row rowsep="1">
|
||
<entry><literal>No</literal></entry>
|
||
<entry>Autres nombres</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>P</literal></entry>
|
||
<entry>Ponctuation</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Pc</literal></entry>
|
||
<entry>Ponctuation de connecteur</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Pd</literal></entry>
|
||
<entry>Tiret de ponctuation</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Pe</literal></entry>
|
||
<entry>Ponctuation de fermeture</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Pf</literal></entry>
|
||
<entry>Ponctuation finale</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Pi</literal></entry>
|
||
<entry>Ponctuation initiale</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Po</literal></entry>
|
||
<entry>Autres ponctuations</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row rowsep="1">
|
||
<entry><literal>Ps</literal></entry>
|
||
<entry>Ponctuation ouvrante</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>S</literal></entry>
|
||
<entry>Symbole</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Sc</literal></entry>
|
||
<entry>Symbole monétaire</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Sk</literal></entry>
|
||
<entry>Symbole de modification</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Sm</literal></entry>
|
||
<entry>Symbole mathématique</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row rowsep="1">
|
||
<entry><literal>So</literal></entry>
|
||
<entry>Autres symboles</entry>
|
||
<entry>Inclut des émojis</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Z</literal></entry>
|
||
<entry>Séparateur</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Zl</literal></entry>
|
||
<entry>Séparateur de ligne</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Zp</literal></entry>
|
||
<entry>Séparateur de paragraphe</entry>
|
||
<entry></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Zs</literal></entry>
|
||
<entry>Séparateur d'espace</entry>
|
||
<entry></entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
<para>
|
||
Les propriétés étendues comme <literal>InMusicalSymbols</literal> ne sont pas supportées
|
||
par PCRE.
|
||
</para>
|
||
<para>
|
||
La sensibilité à la casse de la recherche n'affecte pas les
|
||
séquences d'échappement. Par exemple, <literal>\p{Lu}</literal>
|
||
cherche toujours et uniquement les lettres en majuscules
|
||
</para>
|
||
<para>
|
||
Les jeux de caractères unicodes sont définis comme appartenant à certains scripts.
|
||
Un caractère d'un de ces jeux peut être trouvé en utilisant un
|
||
nom de script. Par exemple :
|
||
</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara><literal>\p{Greek}</literal></simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><literal>\P{Han}</literal></simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<para>
|
||
Ceux qui ne font pas partie d'un script identifié sont regroupés
|
||
dans <literal>Common</literal>. Voici la liste courante des scripts :
|
||
</para>
|
||
<table>
|
||
<title>Scripts supportés</title>
|
||
<tgroup cols="5">
|
||
<tbody>
|
||
<row>
|
||
<entry><literal>Arabic</literal></entry>
|
||
<entry><literal>Armenian</literal></entry>
|
||
<entry><literal>Avestan</literal></entry>
|
||
<entry><literal>Balinese</literal></entry>
|
||
<entry><literal>Bamum</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Batak</literal></entry>
|
||
<entry><literal>Bengali</literal></entry>
|
||
<entry><literal>Bopomofo</literal></entry>
|
||
<entry><literal>Brahmi</literal></entry>
|
||
<entry><literal>Braille</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Buginese</literal></entry>
|
||
<entry><literal>Buhid</literal></entry>
|
||
<entry><literal>Canadian_Aboriginal</literal></entry>
|
||
<entry><literal>Carian</literal></entry>
|
||
<entry><literal>Chakma</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Cham</literal></entry>
|
||
<entry><literal>Cherokee</literal></entry>
|
||
<entry><literal>Common</literal></entry>
|
||
<entry><literal>Coptic</literal></entry>
|
||
<entry><literal>Cuneiform</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Cypriot</literal></entry>
|
||
<entry><literal>Cyrillic</literal></entry>
|
||
<entry><literal>Deseret</literal></entry>
|
||
<entry><literal>Devanagari</literal></entry>
|
||
<entry><literal>Egyptian_Hieroglyphs</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Ethiopic</literal></entry>
|
||
<entry><literal>Georgian</literal></entry>
|
||
<entry><literal>Glagolitic</literal></entry>
|
||
<entry><literal>Gothic</literal></entry>
|
||
<entry><literal>Greek</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Gujarati</literal></entry>
|
||
<entry><literal>Gurmukhi</literal></entry>
|
||
<entry><literal>Han</literal></entry>
|
||
<entry><literal>Hangul</literal></entry>
|
||
<entry><literal>Hanunoo</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Hebrew</literal></entry>
|
||
<entry><literal>Hiragana</literal></entry>
|
||
<entry><literal>Imperial_Aramaic</literal></entry>
|
||
<entry><literal>Inherited</literal></entry>
|
||
<entry><literal>Inscriptional_Pahlavi</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Inscriptional_Parthian</literal></entry>
|
||
<entry><literal>Javanese</literal></entry>
|
||
<entry><literal>Kaithi</literal></entry>
|
||
<entry><literal>Kannada</literal></entry>
|
||
<entry><literal>Katakana</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Kayah_Li</literal></entry>
|
||
<entry><literal>Kharoshthi</literal></entry>
|
||
<entry><literal>Khmer</literal></entry>
|
||
<entry><literal>Lao</literal></entry>
|
||
<entry><literal>Latin</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Lepcha</literal></entry>
|
||
<entry><literal>Limbu</literal></entry>
|
||
<entry><literal>Linear_B</literal></entry>
|
||
<entry><literal>Lisu</literal></entry>
|
||
<entry><literal>Lycian</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Lydian</literal></entry>
|
||
<entry><literal>Malayalam</literal></entry>
|
||
<entry><literal>Mandaic</literal></entry>
|
||
<entry><literal>Meetei_Mayek</literal></entry>
|
||
<entry><literal>Meroitic_Cursive</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Meroitic_Hieroglyphs</literal></entry>
|
||
<entry><literal>Miao</literal></entry>
|
||
<entry><literal>Mongolian</literal></entry>
|
||
<entry><literal>Myanmar</literal></entry>
|
||
<entry><literal>New_Tai_Lue</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Nko</literal></entry>
|
||
<entry><literal>Ogham</literal></entry>
|
||
<entry><literal>Old_Italic</literal></entry>
|
||
<entry><literal>Old_Persian</literal></entry>
|
||
<entry><literal>Old_South_Arabian</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Old_Turkic</literal></entry>
|
||
<entry><literal>Ol_Chiki</literal></entry>
|
||
<entry><literal>Oriya</literal></entry>
|
||
<entry><literal>Osmanya</literal></entry>
|
||
<entry><literal>Phags_Pa</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Phoenician</literal></entry>
|
||
<entry><literal>Rejang</literal></entry>
|
||
<entry><literal>Runic</literal></entry>
|
||
<entry><literal>Samaritan</literal></entry>
|
||
<entry><literal>Saurashtra</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Sharada</literal></entry>
|
||
<entry><literal>Shavian</literal></entry>
|
||
<entry><literal>Sinhala</literal></entry>
|
||
<entry><literal>Sora_Sompeng</literal></entry>
|
||
<entry><literal>Sundanese</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Syloti_Nagri</literal></entry>
|
||
<entry><literal>Syriac</literal></entry>
|
||
<entry><literal>Tagalog</literal></entry>
|
||
<entry><literal>Tagbanwa</literal></entry>
|
||
<entry><literal>Tai_Le</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Tai_Tham</literal></entry>
|
||
<entry><literal>Tai_Viet</literal></entry>
|
||
<entry><literal>Takri</literal></entry>
|
||
<entry><literal>Tamil</literal></entry>
|
||
<entry><literal>Telugu</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Thaana</literal></entry>
|
||
<entry><literal>Thai</literal></entry>
|
||
<entry><literal>Tibetan</literal></entry>
|
||
<entry><literal>Tifinagh</literal></entry>
|
||
<entry><literal>Ugaritic</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>Vai</literal></entry>
|
||
<entry><literal>Yi</literal></entry>
|
||
<entry />
|
||
<entry />
|
||
<entry />
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
<para>
|
||
La séquence <literal>\X</literal> cherche n'importe quel groupe de
|
||
graphème Unicode étendu. Un groupe de graphème est une chaîne
|
||
composée d'un ou plusieurs caractères Unicode qui se combinent
|
||
pour former un seul glyphe. Dans les faits, cela revient à utiliser
|
||
le caractère <literal>.</literal> sachant qu'il va matcher un
|
||
caractère composé, peu importe le nombre de caractères individuels
|
||
nécessaire à l'afficher.
|
||
</para>
|
||
<para>
|
||
Dans les versions PCRE inférieures à 8.32 (ce qui correspond aux
|
||
versions de PHP antérieures à la version 5.4.14 lorsque la
|
||
bibliothèque interne est utilisée), <literal>\X</literal> était
|
||
équivalent à <literal>(?>\PM\pM*)</literal>. Aussi, il matchait
|
||
un caractère sans propriété "mark", suivi par aucun ou plusieurs
|
||
caractères possédant la propriété "mark", et traitait la séquence
|
||
comme un groupe atomique (voir ci-dessous). Les caractères
|
||
avec la propriété "mark" sont typiquement les lettres accentuées
|
||
qui affectent le caractère qui la précède.
|
||
</para>
|
||
<para>
|
||
La recherche de caractères par les propriétés Unicode n'est pas la méthode
|
||
la plus rapide, car PCRE doit chercher une structure qui contient les données
|
||
dans plus de quinze mille caractères. C'est pour cela que les séquences
|
||
traditionnelles comme <literal>\d</literal> et
|
||
<literal>\w</literal> n'utilisent pas les propriétés Unicode dans PCRE.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.anchors">
|
||
<title>Ancres</title>
|
||
<para>
|
||
En dehors d'une classe de caractères, avec les options par
|
||
défaut, <literal>^</literal> est une assertion qui n'est
|
||
vraie que si elle est placée tout au début de la
|
||
chaîne. À l'intérieur d'une classe de caractères,
|
||
<literal>^</literal> a un tout autre sens (voir ci-dessous).
|
||
</para>
|
||
<para>
|
||
<literal>^</literal> 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 <literal>^</literal>, alors le masque est dit ancré
|
||
(il y a une autre construction qui porte cette appellation).
|
||
</para>
|
||
<para>
|
||
<literal>$</literal> 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. À l'intérieur d'une
|
||
classe de caractères, <literal>$</literal> a un tout autre
|
||
sens (voir ci-dessous).
|
||
<literal>$</literal> 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
|
||
<literal>$</literal>, alors le masque est dit ancré (il y
|
||
a une autre construction qui porte cette appellation). <literal>$</literal>
|
||
n'a pas de valeur particulière dans une classe de
|
||
caractères.
|
||
</para>
|
||
<para>
|
||
La signification de <literal>$</literal> 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
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_DOLLAR_ENDONLY</link>
|
||
au moment de la compilation, ou de l'exécution.
|
||
Cette option est inopérante sur <literal>\Z</literal>.
|
||
</para>
|
||
<para>
|
||
La signification de <literal>^</literal> 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 "<literal>\n</literal>". Cela se fait en ajoutant l'option
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link> au moment de
|
||
la compilation ou de l'exécution.
|
||
Par exemple, le masque <literal>/^abc$/</literal> accepte la chaîne
|
||
"<literal>def\nabc</literal>" uniquement en mode multilignes. Par
|
||
conséquent, toutes les parties du masque qui commencent par
|
||
"<literal>^</literal>" ne sont pas ancrées, en mode multilignes.
|
||
L'option <link linkend="reference.pcre.pattern.modifiers">PCRE_DOLLAR_ENDONLY</link>
|
||
est ignorée si l'option
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link> est choisie.
|
||
</para>
|
||
<para>
|
||
À noter que les métacaractères <literal>\A</literal>,
|
||
<literal>\Z</literal>, et <literal>\z</literal> peuvent servir à
|
||
repérer le début et la fin du sujet, et toutes les
|
||
parties du masque qui commenceront par <literal>\A</literal> seront toujours
|
||
ancrées, avec l'option
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link> ou non.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.dot">
|
||
<title>Point</title>
|
||
<para>
|
||
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
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link> le point
|
||
remplace n'importe quel caractère, même le caractère de
|
||
nouvelle ligne. La gestion des points est complètement
|
||
indépendante de <literal>^</literal> et <literal>$</literal>.
|
||
Le seul point commun est que les deux ont un comportement particulier vis-à-vis
|
||
des caractères de nouvelle ligne.
|
||
Le point n'a pas de comportement particulier dans une classe de
|
||
caractères.
|
||
</para>
|
||
<para>
|
||
<emphasis>\C</emphasis> peut être utilisé pour chercher un seul octet.
|
||
Il prend tout son sens en mode <emphasis>UTF-8</emphasis>
|
||
où le point correspond à un caractère entier qui peut être constitué de plusieurs
|
||
octets.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.character-classes">
|
||
<title>Classes de caractères</title>
|
||
<para>
|
||
Un crochet ouvrant <literal>[</literal> introduit une classe de
|
||
caractères, et le crochet fermant <literal>]</literal> la
|
||
conclut. 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 <literal>^</literal> éventuel)
|
||
ou protégé avec un antislash.
|
||
</para>
|
||
<para>
|
||
Une classe de caractères remplace un seul caractère
|
||
dans la chaîne sujet, à moins que le premier
|
||
caractère de la classe soit un accent circonflexe
|
||
<literal>^</literal>, qui représente une négation :
|
||
le caractère ne doit pas se trouver dans la classe. Si
|
||
<literal>^</literal> est nécessaire dans la classe, il
|
||
suffit qu'il ne soit pas le premier caractère, ou bien
|
||
qu'il soit protégé par un antislash.
|
||
</para>
|
||
<para>
|
||
Par exemple, le caractère <literal>[aeiou]</literal> remplace
|
||
n'importe quelle voyelle minuscule, tandis que <literal>[^aeiou]</literal>
|
||
remplace n'importe quel caractère qui n'est pas une voyelle
|
||
minuscule. <literal>^</literal> 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é.
|
||
</para>
|
||
<para>
|
||
Avec l'option d'insensibilité à la casse, toutes les lettres
|
||
d'une classe de caractères représentent en même temps
|
||
la majuscule et la minuscule. Par exemple, <literal>[aeiou]</literal>
|
||
représentera "<literal>A</literal>" ou "<literal>a</literal>", et
|
||
<literal>[^aeiou]</literal> n'acceptera pas "<literal>A</literal>",
|
||
tandis que sans l'option, elle l'accepterait.
|
||
</para>
|
||
<para>
|
||
Le caractère de nouvelle ligne n'est pas traité de
|
||
manière spéciale dans les classes de caractères,
|
||
quelle que soit l'option <link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link>
|
||
ou <link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link>. Une classe
|
||
telle que <literal>[^a]</literal> acceptera toujours une nouvelle ligne.
|
||
</para>
|
||
<para>
|
||
Le signe moins (<literal>-</literal>) est utilisé pour
|
||
spécifier un intervalle de caractères, dans
|
||
une classe. Par exemple, <literal>[d-m]</literal> remplace toutes
|
||
les lettres entre d et m inclus. Si le caractère moins est
|
||
requis dans une classe, il faut le protéger avec un antislash,
|
||
ou le faire apparaître à une position où il ne pourra
|
||
pas être interprété comme une indication d'intervalle,
|
||
c'est-à-dire au début ou à la fin de la classe.
|
||
</para>
|
||
<para>
|
||
Il n'est pas possible d'avoir le caractère crochet fermant
|
||
"<literal>]</literal>" comme fin d'intervalle. Un masque tel que
|
||
<literal>[W-]46]</literal> est compris comme la classe de caractères
|
||
contenant deux caractères ("W" et "-") suivie de la chaîne
|
||
littérale "46]", ce qui fait qu'il va accepter
|
||
"<literal>W46]</literal>" ou "<literal>-46]</literal>". Cependant, si
|
||
"<literal>]</literal>" est protégé avec un antislash, le
|
||
masque <literal>[W-\]46]</literal> est interprété comme
|
||
une classe d'un seul caractère, contenant un intervalle de
|
||
caractères. La valeur octale ou hexadécimale de
|
||
"<literal>]</literal>" peut aussi être utilisée pour déterminer
|
||
les limites de l'intervalle.
|
||
</para>
|
||
<para>
|
||
Les intervalles travaillent sur des séquences ASCII.
|
||
Ils peuvent aussi être précisés avec des valeurs numériques :
|
||
par exemple "<literal>[\000-\037]</literal>".
|
||
Si cet intervalle inclut des lettres utilisées avec une
|
||
option d'insensibilité de casse, les majuscules ou minuscules
|
||
correspondantes seront aussi incluses. Par exemple,
|
||
"<literal>[W-c]</literal>" est équivalent à
|
||
"<literal>[][\^_`wxyzabc]</literal>", avec l'option
|
||
d'insensibilité de casse. Si la table locale de
|
||
caractères est "fr", "<literal>[\xc8-\xcb]</literal>"
|
||
correspond aux caractères accentués.
|
||
</para>
|
||
<para>
|
||
Les types de caractères <literal>\d</literal>,
|
||
<literal>\D</literal>, <literal>\S</literal>, <literal>\s</literal>,
|
||
<literal>\w</literal>, <literal>\W</literal> peuvent aussi intervenir
|
||
dans les classes de caractères. Par exemple,
|
||
"<literal>[][\^_`wxyzabc][\dABCDEF]</literal>" 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
|
||
<literal>[^\W_]</literal> accepte toutes les lettres et les chiffres,
|
||
mais pas les soulignés.
|
||
</para>
|
||
<para>
|
||
Tous les caractères non alphanumériques autres que
|
||
<literal>\, -, ^</literal> (placés en début de chaîne)
|
||
et <literal>]</literal> n'ont pas de signification
|
||
particulière, mais ils ne perdront rien à être protégés.
|
||
Le délimiteur de motif est toujours spécial, et doit être
|
||
protégé lorsqu'il est utilisé à l'intérieur d'une expression.
|
||
</para>
|
||
<para>
|
||
Perl supporte la notation POSIX pour les classes de caractères.
|
||
Elles utilisent des noms entourés par <literal>[:</literal> et
|
||
<literal>:]</literal>. PCRE supporte également cette notation. Par exemple,
|
||
<literal>[01[:alpha:]%]</literal> trouve "0", "1", toute lettre,
|
||
ou encore le caractère "%". Les noms de classe supportés sont :
|
||
<table>
|
||
<title>Classes de caractères</title>
|
||
<tgroup cols="2">
|
||
<tbody>
|
||
<row>
|
||
<entry><literal>alnum</literal></entry>
|
||
<entry>lettres et chiffres</entry></row>
|
||
<row>
|
||
<entry><literal>alpha</literal></entry>
|
||
<entry>lettres</entry></row>
|
||
<row>
|
||
<entry><literal>ascii</literal></entry>
|
||
<entry>codes caractères 0 - 127</entry></row>
|
||
<row>
|
||
<entry><literal>blank</literal></entry>
|
||
<entry>espace ou tabulation uniquement</entry></row>
|
||
<row>
|
||
<entry><literal>cntrl</literal></entry>
|
||
<entry>caractères de contrôle</entry></row>
|
||
<row>
|
||
<entry><literal>digit</literal></entry>
|
||
<entry>chiffres décimaux (identique à \d)</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>graph</literal></entry>
|
||
<entry>caractères d'impression, excluant les espaces</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>lower</literal></entry>
|
||
<entry>lettres en minuscule</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>print</literal></entry>
|
||
<entry>caractères d'impression, incluant les espaces</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>punct</literal></entry>
|
||
<entry>caractères d'impression, excluant les lettres et les chiffres</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>space</literal></entry>
|
||
<entry>espace blanc (pas tout à fait identique à \s)</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>upper</literal></entry>
|
||
<entry>lettres en majuscule</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>word</literal></entry>
|
||
<entry>caractères composant un mot (identique à \w)</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>xdigit</literal></entry>
|
||
<entry>chiffres hexadécimaux</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
Les caractères d'espacement (<literal>space</literal>) sont HT (9), LF (10), VT (11), FF (12), CR (13),
|
||
et l'espace (32). À noter que cette liste inclut le caractère VT (code 11). Ceci rend la classe
|
||
"space" différente de <literal>\s</literal>, qui n'inclut pas ce caractère VT (pour une raison de compatibilité
|
||
Perl).
|
||
</para>
|
||
<para>
|
||
La classe <literal>word</literal> est une extension Perl, et <literal>blank</literal>
|
||
est une extension GNU de Perl 5.8. La négation est une autre extension Perl ; elle est indiquée
|
||
par le caractère <literal>^</literal> après un double-point. Par exemple,
|
||
<literal>[12[:^digit:]]</literal> trouve "1", "2", mais aussi tout caractère qui n'est pas un chiffre.
|
||
</para>
|
||
<para>
|
||
En mode UTF-8, les caractères dont les valeurs sont supérieures à 128 ne seront trouvés par
|
||
aucune des classes de caractères POSIX.
|
||
À partir de libpcre 8.10 certains caractères de classes ont été
|
||
modifiés pour utiliser des caractères de propriétés Unicode, dans ce cas les
|
||
restrictions mentionnées ne s'appliquent pas.
|
||
Se référer au <link xlink:href="&url.pcre.man;">manuel PCRE(3)</link> pour plus de détails.
|
||
</para>
|
||
<para>
|
||
Les propriétés des caractères Unicode peuvent apparaître à l'intérieur d'une
|
||
classe de caractère. Ils ne peuvent pas faire partie d'une étendue.
|
||
Le caractère moins (tiret) après une classe de caractère Unicode satisfera littéralement.
|
||
Essayer de terminer une étendue avec une propriété de caractère Unicode résultera en un avertissement.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.alternation">
|
||
<title>Alternatives</title>
|
||
<para>
|
||
La barre verticale <literal>|</literal> sert à séparer des
|
||
alternatives. Par exemple, dans le masque "<literal>/dupont|martin/</literal>"
|
||
recherche soit "<literal>dupont</literal>", soit "<literal>martin</literal>".
|
||
Le nombre d'alternatives 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 à droite, et la première qui est
|
||
acceptée est utilisée.
|
||
Si les alternatives sont dans un sous-masque, elles ne réussiront
|
||
que si le masque principal réussit aussi.
|
||
</para>
|
||
<para>
|
||
Il est possible d’enregistrer quelle alternative a été sélectionnée en utilisant
|
||
<literal>(*MARK:NOM)</literal> ou <literal>(*:NOM)</literal>.
|
||
Un nombre quelconque de verbes <literal>(*MARK)</literal> peut apparaître, et leurs
|
||
noms n’ont pas besoin d’être uniques. Lorsqu’une correspondance réussit, le nom du
|
||
dernier <literal>(*MARK:NOM)</literal> rencontré sera placé parmi
|
||
les correspondances comme s’il s’agissait d’un groupe de capture appelé <literal>MARK</literal>,
|
||
de sorte qu’il puisse être lu à partir de <parameter>matches</parameter> dans
|
||
<function>preg_match</function> et sera transmis au
|
||
<parameter>callback</parameter> de <function>preg_replace_callback</function> etc.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.internal-options">
|
||
<title>Options internes</title>
|
||
<para>
|
||
Les options <link linkend="reference.pcre.pattern.modifiers">PCRE_CASELESS</link>,
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link>,
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link>,
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_UNGREEDY</link>,
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_EXTRA</link>,
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_EXTENDED</link> et
|
||
PCRE_DUPNAMES peuvent être changées à l'intérieur du masque
|
||
lui-même, avec des séquences mises entre
|
||
"<literal>(?</literal>" et "<literal>)</literal>".
|
||
Les options sont :
|
||
<table>
|
||
<title>Options internes</title>
|
||
<tgroup cols="2">
|
||
<tbody>
|
||
<row>
|
||
<entry><literal>i</literal></entry>
|
||
<entry>pour <link linkend="reference.pcre.pattern.modifiers">PCRE_CASELESS</link></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>m</literal></entry>
|
||
<entry>pour <link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>s</literal></entry>
|
||
<entry>pour <link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>x</literal></entry>
|
||
<entry>pour <link linkend="reference.pcre.pattern.modifiers">PCRE_EXTENDED</link></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>U</literal></entry>
|
||
<entry>pour <link linkend="reference.pcre.pattern.modifiers">PCRE_UNGREEDY</link></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>X</literal></entry>
|
||
<entry>Pour <link linkend="reference.pcre.pattern.modifiers">PCRE_EXTRA</link>
|
||
(plus supporté à partir de PHP 7.3.0)</entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>J</literal></entry>
|
||
<entry>Pour <link linkend="reference.pcre.pattern.modifiers">PCRE_INFO_JCHANGED</link></entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
</para>
|
||
<para>
|
||
Par exemple, <literal>(?im)</literal> rend le masque insensible à
|
||
la casse, et multilignes. Il est possible d'annuler ces options en les
|
||
faisant précéder par un signe <literal>-</literal> : par
|
||
exemple <literal>(?im-sx)</literal>, ajoutera les options
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_CASELESS</link>
|
||
et <link linkend="reference.pcre.pattern.modifiers">PCRE_MULTILINE</link>,
|
||
mais annulera les options
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link>
|
||
et <link linkend="reference.pcre.pattern.modifiers">PCRE_EXTENDED</link>.
|
||
Si une option apparaît avant et après le signe moins, l'option
|
||
sera annulée.
|
||
</para>
|
||
<para>
|
||
Lorsqu'une modification d'option survient au degré le plus haut (et donc, pas dans
|
||
les parenthèses du sous-masque), les modifications sont appliquées dans le reste
|
||
du masque qui suit. Donc, <literal>/ab(?i)c/</literal> valide uniquement
|
||
"abc" et "abC".
|
||
</para>
|
||
<para>
|
||
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 <literal>(a(?i)b)c</literal>
|
||
acceptera <literal>abc</literal> et <literal>aBc</literal>,
|
||
mais aucune autre chaîne (en supposant que <link
|
||
linkend="reference.pcre.pattern.modifiers">PCRE_CASELESS</link> n'est pas
|
||
utilisé). Cela signifie que les options permettent d'avoir
|
||
différentes configurations de recherche pour différentes parties du masque.
|
||
Une séquence d'options dans une alternative affecte toute l'alternative.
|
||
Par exemple :
|
||
|
||
<literal>(a(?i)b|c)</literal>
|
||
|
||
accepte "<literal>ab</literal>", "<literal>aB</literal>", "<literal>c</literal>",
|
||
et "<literal>C</literal>", même si, comme dans le cas de
|
||
"<literal>C</literal>", la première alternative qui porte
|
||
l'option n'est pas prise en compte. Sinon, cela risque d'introduire
|
||
des comportements très étranges
|
||
</para>
|
||
<para>
|
||
Les options spécifiques à PCRE telles
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_UNGREEDY</link> et
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_EXTRA</link> peuvent
|
||
être modifiées de la même manière, en utilisant respectivement les caractères
|
||
U et X. L'option <literal>(?X)</literal> est particulière,
|
||
car elle doit toujours intervenir avant toutes les autres options,
|
||
même au niveau du masque entier. Il vaut mieux l'activer au
|
||
début du masque.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.subpatterns">
|
||
<title>Sous-masques</title>
|
||
<para>
|
||
Les sous-masques sont délimités par des parenthèses,
|
||
et peuvent être imbriqués. Ajouter des sous-masques a deux
|
||
utilités :
|
||
</para>
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>
|
||
Localiser un ensemble d'alternatives. Par exemple, le motif
|
||
<literal>cat(aract|erpillar|)</literal> trouve un des mots "cat",
|
||
"cataract", ou "caterpillar". Sans les parenthèses, cela trouverait
|
||
"cataract", "erpillar" ou la chaîne vide.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
Cela configure le sous-masque comme capturant. Lorsque tout le motif
|
||
correspond, la portion de la sous-chaîne qui correspond au sous-masque
|
||
est passé à l'appelant grâce à l'argument <emphasis>ovector</emphasis>
|
||
de <function>pcre_exec</function>. Les parenthèses ouvrantes sont comptées
|
||
depuis la gauche vers la droite (commençant à 1) jusqu'à obtenir le nombre
|
||
des sous-masques capturants.
|
||
</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
<para>
|
||
Par exemple, soit la chaîne sujet "<literal>le roi soleil</literal>"
|
||
qui est utilisée avec le masque suivant :
|
||
<literal>Le ((roi|prince) (soleil|charmant))</literal>, les sous-masques
|
||
capturés sont "<literal>roi soleil</literal>", "<literal>roi</literal>",
|
||
et "<literal>soleil</literal>", numérotés respectivement 1, 2, et 3.
|
||
</para>
|
||
<para>
|
||
L'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 capturer la valeur trouvée.
|
||
Si une parenthèse ouvrante est suivie de "<literal>?:</literal>",
|
||
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 "<literal>le prince charmant</literal>", utilisé
|
||
avec le masque
|
||
|
||
<literal>Le (( ?:roi|prince) (soleil|charmant))</literal>
|
||
|
||
les chaînes capturées seront "<literal>prince charmant</literal>"
|
||
et "<literal>charmant</literal>", numérotés respectivement 1
|
||
et 2. Le nombre maximal de chaînes capturées est de 65535. Il se peut qu'il
|
||
soit impossible de compiler un masque aussi large, toutefois, ceci dépend des
|
||
options de configuration de libpcre.
|
||
</para>
|
||
<para>
|
||
En guise de raccourci, si n'importe quelle option de configuration
|
||
est requise au début des sous-masques non-capturants, les lettres
|
||
d'option peuvent apparaître entre le signe <literal>"?"</literal>
|
||
et le signe <literal>":"</literal>. Ainsi, les 2 masques
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting>
|
||
<![CDATA[
|
||
(?i:samedi|dimanche)
|
||
(?:(?i)samedi|dimanche)
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
<para>
|
||
captureront exactement les mêmes chaînes. Du fait que les branches
|
||
alternatives sont testées de la gauche vers la droite, et que les
|
||
options ne sont pas réinitialisées tant que le sous masque n'est pas
|
||
atteint, une option de configuration d'une branche n'affecte pas
|
||
les branches sous-jacentes ; ainsi, les 2 masques ci-dessus
|
||
captureront <literal>"SAMEDI"</literal>, mais aussi
|
||
<literal>"Samedi"</literal>.
|
||
</para>
|
||
<para>
|
||
Il est possible de nommer un sous-masque en utilisant la syntaxe
|
||
<literal>(?P<name>pattern)</literal>. Ce sous-masque sera alors
|
||
indexé dans le tableau de concordance par sa position, ainsi
|
||
que par son nom. Il y a deux syntaxes alternatives :
|
||
<literal>(?<name>pattern)</literal> et
|
||
<literal>(?'name'pattern)</literal>.
|
||
</para>
|
||
|
||
<para>
|
||
Quelques fois, il est nécessaire d'avoir plusieurs correspondances en alternant
|
||
les sous groupes dans une expression régulière. Normalement, chacun recevra son
|
||
propre nombre de références arrière même si seulement un d'entre eux ne peut
|
||
correspondre. Pour éviter cela, la syntaxe <literal>(?|</literal> permet d'autoriser
|
||
les nombres dupliqués. Soit l'expression ci-après utilisée avec la chaîne
|
||
<literal>Sunday</literal>:
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting>
|
||
<![CDATA[(?:(Sat)ur|(Sun))day]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
<para>
|
||
Ici, <literal>Sun</literal> est stocké dans la référence arrière 2, alors que la référence
|
||
arrière 1 est vide. La recherche de correspondance de <literal>Saturday</literal> mène donc à
|
||
<literal>Sat</literal> dans la référence arrière 1 alors que la référence arrière 2
|
||
n'existe pas. Changer le masque en utilisant <literal>(?|</literal> résout ce problème:
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting>
|
||
<![CDATA[(?|(Sat)ur|(Sun))day]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
|
||
<para>
|
||
Avec ce masque, à la fois <literal>Sun</literal> et <literal>Sat</literal>
|
||
seront stockés dans la référence arrière 1.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.repetition">
|
||
<title>Répétitions</title>
|
||
<para>
|
||
Les répétitions sont spécifiées avec
|
||
des quantificateurs, qui peuvent être placés à
|
||
la suite des caractères suivants :
|
||
|
||
<itemizedlist>
|
||
<listitem><simpara>Un caractère unique, même s'il s'agit d'un métacaractère</simpara></listitem>
|
||
<listitem><simpara>Le métacaractère . </simpara></listitem>
|
||
<listitem><simpara>Une classe de caractères</simpara></listitem>
|
||
<listitem><simpara>Une référence de retour (voir section suivante)</simpara></listitem>
|
||
<listitem><simpara>Un sous-masque avec parenthèses (à moins que ce ne soit
|
||
une assertion, voir plus loin)</simpara></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
<para>
|
||
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 petits que 65536, et le premier nombre
|
||
doit être égal ou inférieur au second. Par exemple
|
||
|
||
<literal>z{2,4}</literal>
|
||
|
||
accepte "<literal>zz</literal>",
|
||
"<literal>zzz</literal>", ou "<literal>zzzz</literal>". 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étitions attendues. Par exemple :
|
||
|
||
<literal>[aeiou]{3,}</literal>
|
||
|
||
accepte n'importe quelle succession d'au moins 3 voyelles minuscules, tandis
|
||
que
|
||
|
||
<literal>\d{8}</literal>
|
||
|
||
n'accepte que 8 chiffres exactement.
|
||
</para>
|
||
<simpara>
|
||
Avant PHP 8.4.0, une accolade ouvrante apparaissant dans une position où un quantificateur n'est pas autorisé,
|
||
ou qui ne correspond pas à la syntaxe d'un quantificateur, est considérée comme un caractère littéral.
|
||
Par exemple, <literal>{,6}</literal> n'est pas un quantificateur, mais une chaîne littérale de quatre caractères.
|
||
|
||
À partir de PHP 8.4.0, l'extension PCRE est livrée avec la version 10.44 de PCRE2,
|
||
ce qui permet des motifs tels que <literal>\d{,8}</literal> qui sont interprétés comme <literal>\d{0,8}</literal>.
|
||
|
||
De plus, à partir de PHP 8.4.0, les espaces autour des quantificateurs tels que
|
||
<literal>\d{0 , 8}</literal> et <literal>\d{ 0 , 8 }</literal> sont autorisés.
|
||
</simpara>
|
||
<para>
|
||
Le quantificateur {0} est autorisé, mais l'expression est alors
|
||
ignorée.
|
||
</para>
|
||
<para>
|
||
Par convenance (et pour la compatibilité ascendante), les trois
|
||
quantificateurs les plus communs ont une abréviation d'un
|
||
seul caractère :
|
||
<table>
|
||
<title>Quantificateurs sur un seul caractère</title>
|
||
<tgroup cols="2">
|
||
<tbody>
|
||
<row>
|
||
<entry><literal>*</literal></entry>
|
||
<entry>équivalent à <literal>{0,}</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>+</literal></entry>
|
||
<entry>équivalent à <literal>{1,}</literal></entry>
|
||
</row>
|
||
<row>
|
||
<entry><literal>?</literal></entry>
|
||
<entry>équivalent à <literal>{0,1}</literal></entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
</para>
|
||
<para>
|
||
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 :
|
||
|
||
<literal>(a?)*</literal>
|
||
|
||
</para>
|
||
<para>
|
||
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. Toutefois, si
|
||
la répétition du sous-masque ne trouve aucun caractère,
|
||
la boucle est interrompue.
|
||
</para>
|
||
<para>
|
||
Par défaut, les quantificateurs sont dits "gourmands", c'est-à-dire,
|
||
qu'ils cherchent d'abord à trouver le nombre maximal de
|
||
répétitions qui autorisent le succès de la recherche.
|
||
L'exemple classique posé par cette gourmandise est la recherche de
|
||
commentaires d'un programme en C. Les commentaires apparaissent entre les
|
||
séquences <literal>/*....*/</literal> et à l'intérieur
|
||
de ces délimiteurs, les <literal>*</literal> et <literal>/</literal>
|
||
sont autorisés. Appliquer le masque
|
||
|
||
<literal>/\*.*\*/</literal>
|
||
|
||
à la chaîne
|
||
|
||
<literal>/* premier commentaire */ aucun commentaire /* second commentaire */</literal>
|
||
|
||
ne peut réussir, car le masque travaille sur toute la chaîne,
|
||
à cause de la gourmandise du caractère <literal>.*</literal>.
|
||
</para>
|
||
<para>
|
||
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
|
||
|
||
<literal>/\*.*?\*/</literal>
|
||
|
||
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.
|
||
À cause de cette ambiguïté, il peut apparaître des situations
|
||
où il faut le doubler :
|
||
|
||
<literal>\d??\d</literal>
|
||
|
||
Ce masque va tenter de lire un seul chiffre, mais le cas échéant,
|
||
il acceptera 2 chiffres pour permettre à la recherche d'aboutir.
|
||
</para>
|
||
<para>
|
||
Si l'option <link linkend="reference.pcre.pattern.modifiers">PCRE_UNGREEDY</link>
|
||
est activée, (une option qui n'est pas disponible avec Perl) alors
|
||
les quantificateurs sont non gourmands par défaut, mais peuvent être
|
||
rendus gourmands au cas par cas, en ajoutant un point d'interrogation
|
||
après. En d'autres termes, cette option inverse le comportement par
|
||
défaut.
|
||
</para>
|
||
<para>
|
||
Les quantificateurs suivis par <literal>+</literal> sont "possessifs". Ils
|
||
mangent autant de caractères que possible et ne retournent pas
|
||
pour chercher le reste du masque. <literal>.*abc</literal> trouvera
|
||
<literal>"abc"</literal>, tandis que <literal>.*+abc</literal> ne le trouvera
|
||
pas, car <literal>.*+</literal> accapare totalement la chaîne.
|
||
Les quantificateurs possessifs peuvent être utilisés pour
|
||
accélérer le traitement.
|
||
</para>
|
||
<para>
|
||
Lorsqu'un sous-masque est quantifié avec un nombre minimum
|
||
de répétitions, qui soit plus grand que 1, ou avec
|
||
un maximum de répétitions, le masque compilé aura
|
||
besoin de plus de place de stockage, proportionnellement au minimum
|
||
et au maximum.
|
||
</para>
|
||
<para>
|
||
Si un masque commence par <literal>.*</literal> ou <literal>.{0,}</literal>
|
||
et que l'option <link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link>
|
||
(équivalent en Perl à /s) est
|
||
activée, c'est-à-dire en autorisant le remplacement des nouvelles
|
||
lignes par un métacaractè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étacaractère
|
||
<literal>\A</literal>. Dans le cas où on sait d'avance qu'il
|
||
n'y aura pas de caractère de nouvelle ligne, activer l'option
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link> et commencer
|
||
le masque par <literal>.*</literal> permet d'optimiser le masque.
|
||
Alternativement, on peut utiliser <literal>^</literal> pour ancrer
|
||
explicitement le masque.
|
||
</para>
|
||
<para>
|
||
Lorsqu'un sous-masque capturant est répété, la valeur capturée est la
|
||
dernière. Par exemple, après que
|
||
|
||
<literal>(inter[net]{3}\s*)+</literal>
|
||
|
||
ait été appliqué à "<literal>internet interne</literal>",
|
||
la valeur de la chaîne capturée est "<literal>interne</literal>".
|
||
Cependant, s'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 :
|
||
|
||
<literal>/(a|(b))+/</literal>
|
||
|
||
accepte "<literal>aba</literal>" et
|
||
la deuxième valeur capturée est "<literal>b</literal>".
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.back-references">
|
||
<title>Références arrières </title>
|
||
<para>
|
||
En dehors des classes de caractères, un antislash 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 capturants précédents.
|
||
</para>
|
||
<para>
|
||
Cependant, si le nombre décimal suivant l'antislash 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 captures
|
||
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. Une "référence arrière vers l'avant" peut avoir du sens
|
||
lorsqu'une répétition est isolée et que le sous masque à droite a participé
|
||
à l'itération précédente. Voir la section sur les
|
||
<link linkend="regexp.reference.escape">séquences d'échappements</link>
|
||
pour plus de détails à propos du nombre de chiffres qui suivent l'antislash.
|
||
</para>
|
||
<para>
|
||
La référence arrière remplace ce qui a
|
||
été capturé par un sous-masque dans le
|
||
masque courant, plutôt que remplacer le sous-masque
|
||
lui-même. Ainsi
|
||
|
||
<literal>(calme|rapide) et \1ment</literal>
|
||
|
||
trouvera "<literal>calme et calmement</literal>"
|
||
et "<literal>rapide et rapidement</literal>", mais pas
|
||
"<literal>calme et rapidement</literal>". Si la recherche tient
|
||
compte de la casse, alors la casse de la chaîne
|
||
capturée sera importante. Par exemple,
|
||
|
||
<literal>((?i)rah)\s+\1</literal>
|
||
|
||
trouve "<literal>rah rah</literal>"
|
||
et "<literal>RAH RAH</literal>", mais pas "<literal>RAH rah</literal>",
|
||
même si le sous-masque capturant initial ne tenait pas compte
|
||
de la casse.
|
||
</para>
|
||
<para>
|
||
Il peut y avoir plusieurs références arrière dans
|
||
le même sous-masque. Si un sous-masque n'a pas été
|
||
utilisé dans une recherche, alors les références
|
||
arrière échoueront. Par exemple
|
||
|
||
<literal>(a|(bc))\2</literal>
|
||
|
||
ne réussira jamais si la chaîne sujet commence par
|
||
"<literal>a</literal>" plutôt que par "<literal>bc</literal>".
|
||
Étant donné qu'il peut y avoir jusqu'à 99 références
|
||
arrière, tous les chiffres après l'antislash sont
|
||
considérés comme 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 <link linkend="reference.pcre.pattern.modifiers">PCRE_EXTENDED</link>
|
||
est activée, on peut utiliser un espace.
|
||
Sinon, un commentaire vide fait l'affaire.
|
||
</para>
|
||
<para>
|
||
Une référence arrière qui intervient à l'intérieur de
|
||
parenthèses auxquelles elle fait référence
|
||
échouera dès que le sous-masque sera utilisé. Par exemple,
|
||
|
||
<literal>(a\1)</literal>
|
||
|
||
échouera toujours. Cependant, ces
|
||
références peuvent être utiles dans les
|
||
sous-masques répétitifs. Par exemple, le masque
|
||
"<literal>(a|b\1)+</literal>" pourra convenir pour "<literal>a</literal>",
|
||
"<literal>aba</literal>", "<literal>ababba</literal>", etc.
|
||
À 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'ait 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.
|
||
</para>
|
||
<para>
|
||
La séquence d'échappement <literal>\g</literal>
|
||
peut être utilisée pour le référencement absolu et relatif des
|
||
sous-masques. Cette séquence doit être suivie par un nombre non signé
|
||
ou négatif, entouré optionnellement par des accolades. La séquence
|
||
<literal>\1</literal>, <literal>\g1</literal> et <literal>\g{1}</literal>
|
||
sont identiques. L'utilisation de ce masque avec un nombre non signé peut
|
||
aider à ne pas le confondre lors de l'utilisation de nombre suivi d'un
|
||
antislash. Cette séquence aide à distinguer les références arrière
|
||
lors de l'utilisation de caractères octaux et rend également plus facile
|
||
d'avoir une référence arrière suivie par un nombre littéral, c.-à-d.
|
||
<literal>\g{2}1</literal>.
|
||
</para>
|
||
<para>
|
||
L'utilisation de la séquence <literal>\g</literal> avec un nombre négatif
|
||
indique une référence relative. Par exemple, <literal>(foo)(bar)\g{-1}</literal>
|
||
trouvera la séquence "foobarbar" et <literal>(foo)(bar)\g{-2}</literal> trouvera
|
||
la séquence "foobarfoo". Ceci peut être pratique dans ce gros masque
|
||
comme alternative afin de conserver une trace du nombre de sous-masques
|
||
afin de référencer un sous-masque précédant spécifique.
|
||
</para>
|
||
<para>
|
||
Les références arrière du sous-masque nommé peuvent être
|
||
utilisées sous la forme
|
||
<literal>(?P=name)</literal>,
|
||
<literal>\k<name></literal>, <literal>\k'name'</literal>,
|
||
<literal>\k{name}</literal>, <literal>\g{name}</literal>,
|
||
<literal>\g<name></literal> ou <literal>\g'name'</literal>.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.assertions">
|
||
<title>Assertions</title>
|
||
<para>
|
||
Une assertion est un test sur les caractères suivants ou
|
||
précédents celui qui est en cours d'étude. Ce
|
||
test ne consomme pas de caractères (ie, on ne déplace
|
||
pas le pointeur de caractères). Les assertions simples sont
|
||
codées avec <literal>\b</literal>, <literal>\B</literal>,
|
||
<literal>\A</literal>, <literal>\Z</literal>, <literal>\z</literal>,
|
||
<literal>^</literal> et <literal>$</literal>, et sont décrites
|
||
dans les <link linkend="regexp.reference.escape">séquences d'échappement</link>.
|
||
Il existe cependant des types d'assertions plus complexes, codées sous la forme
|
||
de sous-masques. Il en existe deux types : celles qui travaillent
|
||
<emphasis>au-delà</emphasis> de la position courante, et celles qui
|
||
travaillent <emphasis>en-deçà</emphasis>.
|
||
</para>
|
||
<para>
|
||
Une assertion se comporte comme un sous-masque, hormis le fait qu'elle
|
||
ne déplace pas le pointeur de position. Les <emphasis>assertions avant</emphasis>
|
||
commencent par <literal>(?=</literal> pour les assertions positives, et
|
||
par <literal>(?!</literal>, pour les assertions négatives. Par exemple :
|
||
|
||
<literal>\w+(?=;)</literal>
|
||
|
||
s'assure qu'un mot est suivi d'un point-virgule,
|
||
mais n'inclut pas le point virgule dans la capture et <literal>foo(?!bar)</literal>
|
||
trouve toutes les occurrences de "foo" qui ne sont pas suivies par "bar".
|
||
À noter que,
|
||
|
||
<literal>(?!foo)bar</literal>
|
||
|
||
en est proche, mais ne trouve pas une
|
||
occurrence de "<literal>bar</literal>" qui soit précédée
|
||
par quelque chose d'autre que "<literal>foo</literal>"; il
|
||
trouve toutes les occurrences de "<literal>bar</literal>",
|
||
quel que soit ce qui le précède, car l'assertion
|
||
|
||
<literal>(?!foo)</literal>
|
||
|
||
est toujours vraie quand les trois caractères suivants sont
|
||
"<literal>bar</literal>". Une assertion arrière est ici
|
||
nécessaire.
|
||
</para>
|
||
<para>
|
||
Les <emphasis>assertions</emphasis> arrières commencent par <literal>(?<=</literal>
|
||
pour les assertions positives, et <literal>(?<!</literal> pour les
|
||
assertions négatives. Par exemple :
|
||
|
||
<literal>(?<!foo)bar</literal>
|
||
|
||
trouve les occurrences de "<literal>bar</literal>" qui ne sont pas
|
||
précédées par "<literal>foo</literal>". Le contenu d'une référence
|
||
arrière est limité de telle façon que les chaînes qu'il utilise
|
||
soient 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. Par exemple,
|
||
|
||
<literal>(?<=bullock|donkey)</literal>
|
||
|
||
est autorisé, tandis que
|
||
|
||
<literal>(?<!dogs?|cats?)</literal>
|
||
|
||
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ère. C'est une
|
||
amélioration du fonctionnement de Perl 5.005, qui impose
|
||
aux alternatives d'avoir toute la même taille. Une
|
||
assertion telle que
|
||
|
||
<literal>(?<=ab(c|de))</literal>
|
||
|
||
n'est pas autorisée, car l'assertion de bas niveau (la deuxième,
|
||
ici) a deux possibilités de longueurs différentes. Pour
|
||
la rendre acceptable, il faut écrire
|
||
|
||
<literal>(?<=abc|abde)</literal>
|
||
|
||
L'implémentation des assertions arrière déplace
|
||
temporairement le pointeur de position vers l'arrière, et cherche
|
||
à vérifier l'assertion. Si le nombre de caractères
|
||
est différent, la position ne sera pas correcte, et l'assertion
|
||
échouera. La combinaison d'assertions arrière avec des
|
||
sous-masques peut être particulièrement pratique à
|
||
fin des chaînes. Un exemple est donné à la fin de
|
||
cette section.
|
||
</para>
|
||
<para>
|
||
Plusieurs assertions peuvent intervenir successivement. Par exemple,
|
||
le masque
|
||
|
||
<literal>(?<=\d{3})(?<!999)foo</literal>
|
||
|
||
recherche les chaînes "<literal>foo</literal>" précédées
|
||
par trois chiffres qui ne sont pas "999". À noter que chaque assertion
|
||
est appliquée indépendamment, au même point de
|
||
la chaîne à traiter. Tout d'abord, il est
|
||
vérifié que les trois premiers caractères ont
|
||
tous des chiffres, puis on s'assure que ces trois caractères
|
||
ne sont pas "<literal>999</literal>". Le masque précédant
|
||
n'accepte pas "<literal>foo</literal>" précédé de
|
||
6 caractères, les trois premiers étant des chiffres et
|
||
les trois suivants étant différents de "<literal>999</literal>".
|
||
Par exemple, ce masque n'acceptera pas la chaîne
|
||
"<literal>123abcfoo</literal>". Pour ce faire, il faut utiliser le masque
|
||
suivant :
|
||
|
||
<literal>(?<=\d{3}...)(?<!999)foo</literal>.
|
||
|
||
</para>
|
||
<para>
|
||
Dans ce masque, la première assertion vérifie les six premiers
|
||
caractères, s'assure que les trois premiers sont des entiers,
|
||
et la deuxième assertion s'assure que les trois derniers
|
||
caractères ne sont pas "<literal>999</literal>".
|
||
</para>
|
||
<para>
|
||
De plus, les assertions peuvent être imbriquées :
|
||
|
||
<literal>(?<=(?<!foo)bar)baz</literal>
|
||
|
||
recherche les occurrences de "<literal>baz</literal>" qui sont
|
||
précédées par "<literal>bar</literal>", qui,
|
||
à son tour, n'est pas précédé par
|
||
"<literal>foo</literal>". Au contraire,
|
||
|
||
<literal>(?<=\d{3}...(?<!999))foo</literal>
|
||
|
||
est un autre masque, qui recherche les caractères "<literal>foo</literal>",
|
||
précédés par trois chiffres, suivis de trois
|
||
autres caractères qui ne forment pas "<literal>999</literal>".
|
||
</para>
|
||
<para>
|
||
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.
|
||
</para>
|
||
<para>
|
||
200 assertions au maximum sont autorisées.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.onlyonce">
|
||
<title>Sous-masques uniques</title>
|
||
<para>
|
||
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.
|
||
</para>
|
||
<para>
|
||
Considérons, par exemple, le masque <literal>\d+foo</literal>
|
||
appliqué à la ligne
|
||
|
||
<literal>123456bar</literal>.
|
||
|
||
</para>
|
||
<para>
|
||
Après avoir tenté d'utiliser les 6 chiffres suivis
|
||
de "<literal>foo</literal>" qui font échouer, l'action habituelle
|
||
sera de réessayer avec 5 chiffres, puis avec 4, et ainsi de
|
||
suite jusqu'à l'échec final. Un sous-masque évalué une seule fois
|
||
permettrait d'indiquer que lorsqu'une partie du masque est trouvée,
|
||
elle n'a pas besoin d'être réévaluée à chaque tentative. Ceci
|
||
conduirait à ce que la recherche échoue immédiatement après le
|
||
premier test. Ces assertions ont leur propre notation, commençant avec
|
||
<literal>(?></literal> comme ceci :
|
||
|
||
<literal>(?>\d+)bar</literal>
|
||
</para>
|
||
<para>
|
||
Ce type de parenthèses verrouille le sous-masque qu'il contient
|
||
une fois qu'il a été trouvé, et empêche un
|
||
échec ultérieur d'y repasser, mais autorise à
|
||
revenir plus loin en arrière.
|
||
</para>
|
||
<para>
|
||
Une autre description est que les sous-masques de ce type
|
||
recherchent les chaînes de caractères, et ancre le sous-masque
|
||
à l'intérieur de la chaîne.
|
||
</para>
|
||
<para>
|
||
Les sous-masques uniques ne sont pas capturants. Des cas simples comme
|
||
ceux présentés ci-dessus peuvent être pris comme
|
||
des situations maximales, qui réservent le maximum de
|
||
caractères. En effet, alors que <literal>\d+</literal> et
|
||
<literal>\d+?</literal> ajustent le nombre de chiffres trouvés
|
||
de manière à laisser la possibilité au masque de
|
||
réussir, <literal>(?>\d+)</literal> ne peut retenir que la
|
||
séquence entière de chiffres.
|
||
</para>
|
||
<para>
|
||
Cette construction peut contenir un nombre arbitraire de sous-masques
|
||
complexes, et ils peuvent être imbriqués.
|
||
</para>
|
||
<para>
|
||
Les sous-masques uniques ne peuvent être utilisés qu'avec
|
||
les assertions arrière, pour effectuer une recherche efficace
|
||
en fin de chaîne. Considérons un masque simple tel
|
||
|
||
<literal>abcd$</literal>
|
||
|
||
appliqué à une très longue chaîne qui ne lui correspond pas.
|
||
À cause du système de recherche de gauche à droite, PCRE va
|
||
commencer par rechercher un "<literal>a</literal>" dans la
|
||
chaîne sujet, puis vérifier si ce qui suit convient au reste
|
||
du masque. Si le masque est spécifié sous la forme
|
||
|
||
<literal>^.*abcd$</literal>
|
||
|
||
alors, la séquence <literal>.*</literal> 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
|
||
"<literal>a</literal>" 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
|
||
|
||
<literal>^(?>.*)(?<=abcd)</literal>
|
||
|
||
alors il n'y aurait pas de retour en arrière, pour satisfaire
|
||
la séquence <literal>.*</literal>, 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 termes de performances et de temps de recherche.
|
||
</para>
|
||
<para>
|
||
Lorsqu'un masque contient une répétition illimitée
|
||
dans un sous-masque, qui contient lui-même un nombre
|
||
illimité de répétiteurs, l'utilisation des
|
||
sous-masques à utilisation unique est la seule façon
|
||
d'éviter l'échec de la recherche après un
|
||
temps de calcul trop long.
|
||
Le masque
|
||
|
||
<literal>(\D+|<\d+>)*[!?]</literal>
|
||
|
||
recherche un nombre illimité de sous-chaînes, qui contiennent soit
|
||
des non-chiffres, soit des chiffres inclus dans <>, suivi soit
|
||
par <literal>!</literal> ou par <literal>?</literal>. Lorsqu'il trouve
|
||
une solution, ce masque va très vite. Mais, lorsqu'il est
|
||
appliqué à une chaîne telle :
|
||
|
||
<literal>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</literal>,
|
||
|
||
il lui faut beaucoup de temps pour annoncer un échec. Cela est
|
||
dû au fait que la chaîne peut être divisée en deux
|
||
sous-chaînes d'un grand nombre de façons, et qu'elles
|
||
ont toutes été essayées. (Cet exemple utilisait
|
||
<literal>[!?]</literal> plutôt qu'un caractère simple, car
|
||
PCRE et PHP utilisent une optimisation qui leur permet de détecter
|
||
rapidement l'échec lorsqu'un caractère unique est
|
||
trouvé. Il se souvient du dernier caractère qui est
|
||
attendu, et s'aperçoit rapidement qu'il n'y a pas ce caractère).
|
||
Si le masque utilisé est
|
||
|
||
<literal>((?>\D+)|<\d+>)*[!?]</literal>
|
||
|
||
les séquences de chiffres ne peuvent pas être
|
||
trouvées, et l'échec intervient rapidement.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.conditional">
|
||
<title>Les sous-masques conditionnels</title>
|
||
<para>
|
||
Il est possible de lier un sous-masque à 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
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting>
|
||
<![CDATA[
|
||
(?(condition)masque positif)
|
||
(?(condition) masque positif | masque négatif)
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
<para>
|
||
Si les conditions sont satisfaites, le masque positif est utilisé,
|
||
sinon, le masque négatif est utilisé, si présent.
|
||
S'il y a plus de deux possibilités, une erreur est générée
|
||
à la compilation.
|
||
</para>
|
||
<para>
|
||
Il y a deux types de conditions : si le texte entre les parenthèses
|
||
est une séquence de chiffres, 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
|
||
significatifs pour le rendre plus compréhensible (on supposera
|
||
l'option <link linkend="reference.pcre.pattern.modifiers">PCRE_EXTENDED</link>
|
||
activée) et qui est divisé en trois parties
|
||
pour simplifier les explications :
|
||
</para>
|
||
<informalexample>
|
||
<programlisting>
|
||
<![CDATA[
|
||
( \( )? [^()]+ (?(1) \) )
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
<para>
|
||
La première partie recherche une parenthèse ouvrante
|
||
optionnelle et, si elle existe, elle est capturée. La deuxième
|
||
partie recherche une séquence de caractères qui ne contiennent
|
||
pas de parenthèses. La troisième partie est
|
||
conditionnée à la première, et s'assure que s'il
|
||
y a 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 lettres,
|
||
éventuellement placées entre parenthèses.
|
||
</para>
|
||
<para>
|
||
Si la condition est la chaîne <literal>(R)</literal>, elle sera
|
||
satisfaite si un appel récursif au masque ou au sous-masque
|
||
a été fait. Au premier appel, la condition n'est pas vérifiée.
|
||
</para>
|
||
<para>
|
||
Si la condition n'est pas une séquence de chiffres, 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êmes conditions que
|
||
le précédent) et avec deux possibilités en seconde ligne :
|
||
</para>
|
||
|
||
<informalexample>
|
||
<programlisting>
|
||
<![CDATA[
|
||
(?(?=[^a-z]*[a-z])
|
||
\d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} )
|
||
]]>
|
||
</programlisting>
|
||
</informalexample>
|
||
<para>
|
||
La condition est une assertion avant positive, qui recherche une
|
||
séquence optionnelle de caractères non-lettre. En d'autres
|
||
termes, elle teste la présence 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 <literal>dd-aaa-dd</literal> ou
|
||
<literal>dd-dd-dd</literal>, avec "<literal>aaa</literal>" qui sont des
|
||
lettres, et <literal>dd</literal> qui sont des chiffres.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.comments">
|
||
<title>Commentaires</title>
|
||
<para>
|
||
La séquence <literal>(?#</literal> marque le début d'un commentaire,
|
||
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.
|
||
</para>
|
||
<para>
|
||
Si l'option <link linkend="reference.pcre.pattern.modifiers">PCRE_EXTENDED</link>
|
||
est activée, les caractères dièses
|
||
<literal>#</literal> non protégés en dehors d'une classe de
|
||
caractères introduisent un commentaire qui continuera jusqu'à
|
||
la prochaine ligne dans le masque.
|
||
</para>
|
||
<para>
|
||
<example>
|
||
<title>Usage de commentaire dans un masque PCRE</title>
|
||
<programlisting role="php">
|
||
<![CDATA[
|
||
<?php
|
||
|
||
$subject = 'test';
|
||
|
||
/* (?# can be used to add comments without enabling PCRE_EXTENDED */
|
||
$match = preg_match('/te(?# this is a comment)st/', $subject);
|
||
var_dump($match);
|
||
|
||
/* Whitespace and # is treated as part of the pattern unless PCRE_EXTENDED is enabled */
|
||
$match = preg_match('/te #~~~~
|
||
st/', $subject);
|
||
var_dump($match);
|
||
|
||
/* When PCRE_EXTENDED is enabled, all whitespace data characters and anything
|
||
that follows an unescaped # on the same line is ignored */
|
||
$match = preg_match('/te #~~~~
|
||
st/x', $subject);
|
||
var_dump($match);
|
||
]]>
|
||
</programlisting>
|
||
&example.outputs;
|
||
<screen>
|
||
<![CDATA[
|
||
int(1)
|
||
int(0)
|
||
int(1)
|
||
]]>
|
||
</screen>
|
||
</example>
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.recursive">
|
||
<title>Masques récursifs</title>
|
||
<para>
|
||
Considérons le cas où il faut rechercher dans une
|
||
chaîne avec un niveau d'imbrications infini de
|
||
parenthèses. Sans l'aide de la récursivité, le
|
||
mieux que nous puissions obtenir est de créer un masque avec un
|
||
niveau fixé de profondeur d'imbrication. Il n'est pas possible
|
||
de traiter des masques à niveau d'imbrication variable.
|
||
PCRE fournit un nouvel outil expérimental qui permet
|
||
d'utiliser la récursivité dans les masques (entre autres).
|
||
L'option <literal>(?R)</literal> est fournie pour servir la cause de
|
||
la récursivité. Le masque suivant résout le
|
||
problème des parenthèses (l'option
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_EXTENDED</link> est
|
||
utilisée pour ignorer les espaces) :
|
||
|
||
<literal>\( ( (?>[^()]+) | (?R) )* \)</literal>
|
||
</para>
|
||
<para>
|
||
Tout d'abord, le masque recherche une parenthèse ouvrante. Puis,
|
||
il recherche n'importe quel nombre de sous-chaînes qui sont soit
|
||
des séquences de caractères non-parenthèses, ou
|
||
bien une recherche récursive avec le même masque (c.-à-d.
|
||
une chaîne correctement incluse entre parenthèses).
|
||
Finalement, il recherche une parenthèse fermante.
|
||
</para>
|
||
<para>
|
||
Cet exemple particulier contient un nombre illimité de
|
||
répétitions imbriquées, ce qui fait que
|
||
l'utilisation de sous-chaînes à utilisation unique
|
||
pour rechercher les séquences de caractères
|
||
non-parenthèses est important, lorsqu'il s'applique à
|
||
une chaîne qui n'est pas valide. Par exemple, si on l'applique
|
||
à
|
||
|
||
<literal>(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()</literal>
|
||
|
||
la réponse arrive rapidement. Sinon, si les sous-chaînes
|
||
à utilisation unique ne sont pas utilisées, la
|
||
recherche peut prendre un temps très long, car il existe
|
||
de très nombreuses combinaisons de <literal>+</literal> et
|
||
<literal>*</literal> à tester avant de conclure à
|
||
l'échec.
|
||
</para>
|
||
<para>
|
||
Les valeurs utilisées pour capturer les sous-masques sont celles
|
||
utilisées par les niveaux les plus hauts de
|
||
récursivité, auxquels la valeur est fixée.
|
||
Si le masque précédent est utilisé avec
|
||
|
||
<literal>(ab(cd)ef)</literal>
|
||
|
||
la valeur de la parenthèse capturante est "<literal>ef</literal>",
|
||
qui est la dernière valeur lue au niveau supérieur. Si de nouvelles
|
||
parenthèses sont ajoutées, par exemple :
|
||
|
||
<literal>\( ( ( (?>[^()]+) | (?R) )* ) \)</literal>
|
||
|
||
alors la chaîne capturée est "<literal>ab(cd)ef</literal>",
|
||
c'est-à-dire le contenu de la parenthèse capturante
|
||
de plus haut niveau. S'il y a plus de 15 parenthèses
|
||
capturantes dans une chaîne, PCRE doit utiliser plus
|
||
de mémoire pour stocker ces données. S'il ne
|
||
peut obtenir cette mémoire supplémentaire, il ne fait
|
||
que sauver les 15 premières, car il n'y a pas moyen de
|
||
générer une erreur de mémoire dans le cadre d'une récursivité.
|
||
</para>
|
||
|
||
<para>
|
||
<literal>(?1)</literal>, <literal>(?2)</literal> et suivants
|
||
peuvent être également utilisés pour les sous masques récursifs. Il est également
|
||
possible d'utiliser les sous masques nommés : <literal>(?P>foo)</literal> ou
|
||
<literal>(?&name)</literal>.
|
||
</para>
|
||
<para>
|
||
Si la syntaxe pour une référence de sous-masque récursif (soit par un
|
||
nombre ou par un nom) est utilisée en dehors des parenthèses à laquelle
|
||
elle fait référence, il opère comme une sous-routine dans un langage
|
||
de programmation. Un exemple ci-dessus a montré que le masque
|
||
<literal>(sens|respons)e and \1ibility</literal>
|
||
trouvera <literal>"sense and sensibility"</literal> et
|
||
<literal>"response and responsibility"</literal>, mais pas
|
||
<literal>"sense and responsibility"</literal>. Si on utilise plutôt le masque
|
||
<literal>(sens|respons)e and (?1)ibility</literal>
|
||
alors, il trouvera <literal>"sense and responsibility"</literal>
|
||
tout comme les deux autres chaînes.
|
||
De telles références doivent, cependant, suivre le sous-masque auquel
|
||
elles se réfèrent.
|
||
</para>
|
||
|
||
<para>
|
||
La longueur maximale d'un sujet correspond au plus grand nombre positif
|
||
qu'une variable entière peut contenir. Cependant, PCRE utilise la récursivité
|
||
pour gérer les sous-masques et les répétitions infinies. Ce qui signifie
|
||
que l'espace disponible pour la pile peut limiter la taille du sujet qui peut
|
||
être passé à certains masques.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="regexp.reference.performance">
|
||
<title>Performance</title>
|
||
<para>
|
||
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 <literal>[aeiou]</literal> plutôt qu'une alternative
|
||
<literal>(a|e|i|o|u)</literal>.
|
||
En général, le masque le plus simple, qui permette
|
||
la recherche désirée est le plus efficace. Le livre
|
||
de Jeffrey Friedl's contient de nombreuses études à
|
||
propos de l'optimisation des expressions régulières.
|
||
</para>
|
||
<para>
|
||
Lorsqu'un masque commence par.* et que l'option
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link> est
|
||
activée, le masque est implicitement ancré par PCRE,
|
||
étant donné qu'il ne peut que rechercher au début
|
||
de la chaîne. Cependant, si l'option
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link> n'est pas
|
||
activée, PCRE ne peut faire aucune optimisation, car le
|
||
métacaractère point "<literal>.</literal>"
|
||
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,
|
||
|
||
<literal>(.*)second</literal>
|
||
|
||
acceptera la chaîne "<literal>premier \net second</literal>"
|
||
(avec "<literal>\n</literal>" qui remplace la nouvelle ligne),
|
||
et la première chaîne capturée sera "<literal>et</literal>".
|
||
Afin d'effectuer la recherche, PCRE va essayer d'appliquer le masque
|
||
à partir de chaque début de ligne.
|
||
</para>
|
||
<para>
|
||
Lors de l'utilisation d'un tel masque avec des chaînes qui ne contiennent
|
||
pas de caractères de nouvelle ligne, les meilleures performances
|
||
seront atteintes avec l'option
|
||
<link linkend="reference.pcre.pattern.modifiers">PCRE_DOTALL</link>, ou en ancrant le
|
||
masque avec <literal>^.*</literal>. Cela évite à PCRE
|
||
de scanner toute la chaîne pour rechercher un caractère
|
||
de nouvelle ligne et recommencer la recherche.
|
||
</para>
|
||
<para>
|
||
Attention aux masques qui contiennent des quantificateurs infinis
|
||
imbriqués. Ils peuvent demander un temps de calcul très
|
||
long, lorsque appliqués à une chaîne qui ne
|
||
correspond pas à ce masque. Par exemple,
|
||
|
||
<literal>(a+)*</literal>
|
||
|
||
</para>
|
||
<para>
|
||
Ce masque peut accepter "<literal>aaaa</literal>" de 33 manières
|
||
différentes, et ce nombre croît rapidement avec la taille
|
||
de la chaîne (le quantificateur <literal>*</literal> peut prendre
|
||
les valeurs de 0, 1, 2, 3, ou 4, et pour chaque cas non nul, le
|
||
quantificateur <literal>+</literal> peut prendre différentes
|
||
valeurs). Lorsque le reste de la chaîne est tel que l'on s'achemine
|
||
vers un échec, PCRE doit en principe vérifier
|
||
toutes les possibilités, et cela prend un temps
|
||
extrêmement long.
|
||
</para>
|
||
<para>
|
||
Un optimiseur repère les cas les plus simples, tel que
|
||
|
||
<literal>(a+)*b</literal>
|
||
|
||
où un caractère simple suit les quantificateurs.
|
||
Avant de partir dans les procédures standards de recherche, PCRE
|
||
s'assure qu'il y a au moins un "<literal>b</literal>" dans la
|
||
chaîne, et si ce n'est pas le cas, l'échec est
|
||
annoncé immédiatement. Sinon, il n'y a pas
|
||
d'optimisation dans la recherche. Il est possible de voir la
|
||
différence de comportement avec le masque suivant :
|
||
|
||
<literal>(a+)*\d</literal>.
|
||
|
||
Le premier retourne un échec quasi-immédiatement, s'il est appliqué à
|
||
une ligne de "<literal>a</literal>", alors que le second masque
|
||
prend un temps significatif pour une chaîne de plus de
|
||
20 caractères.
|
||
</para>
|
||
</section>
|
||
</chapter>
|
||
<!-- Keep this comment at the end of the file
|
||
Local variables:
|
||
mode: sgml
|
||
sgml-omittag:t
|
||
sgml-shorttag:t
|
||
sgml-minimize-attributes:nil
|
||
sgml-always-quote-attributes:t
|
||
sgml-indent-step:1
|
||
sgml-indent-data:t
|
||
indent-tabs-mode:nil
|
||
sgml-parent-document:nil
|
||
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
||
sgml-exposed-tags:nil
|
||
sgml-local-catalogs:nil
|
||
sgml-local-ecat-files:nil
|
||
End:
|
||
vim600: syn=xml fen fdm=syntax fdl=2 si
|
||
vim: et tw=78 syn=sgml
|
||
vi: ts=1 sw=1
|
||
-->
|