<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/reference.pcre.pattern.syntax.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'fr',
  ),
  'this' => 
  array (
    0 => 'regexp.reference.recursive.php',
    1 => 'Masques r&eacute;cursifs',
    2 => 'Masques r&eacute;cursifs',
  ),
  'up' => 
  array (
    0 => 'reference.pcre.pattern.syntax.php',
    1 => 'Fonctionnement des expressions r&eacute;guli&egrave;res',
  ),
  'prev' => 
  array (
    0 => 'regexp.reference.comments.php',
    1 => 'Commentaires',
  ),
  'next' => 
  array (
    0 => 'regexp.reference.performance.php',
    1 => 'Performance',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'fr',
    'path' => 'reference/pcre/pattern.syntax.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="regexp.reference.recursive" class="section">
  <h2 class="title">Masques récursifs</h2>
  <p class="para">
   Considérons le cas où il faut rechercher dans une
   chaîne avec un niveau d&#039;imbrications infini de
   parenthèses. Sans l&#039;aide de la récursivité, le
   mieux que nous puissions obtenir est de créer un masque avec un
   niveau fixé de profondeur d&#039;imbrication. Il n&#039;est pas possible
   de traiter des masques à niveau d&#039;imbrication variable.
   PCRE fournit un nouvel outil expérimental qui permet
   d&#039;utiliser la récursivité dans les masques (entre autres).
   L&#039;option <code class="literal">(?R)</code> est fournie pour servir la cause de
   la récursivité. Le masque suivant résout le
   problème des parenthèses (l&#039;option
   <a href="reference.pcre.pattern.modifiers.php" class="link">PCRE_EXTENDED</a> est
   utilisée pour ignorer les espaces) :
   
   <code class="literal">\( ( (?&gt;[^()]+) | (?R) )* \)</code>
  </p>
  <p class="para">
   Tout d&#039;abord, le masque recherche une parenthèse ouvrante. Puis,
   il recherche n&#039;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.
  </p>
  <p class="para">
   Cet exemple particulier contient un nombre illimité de
   répétitions imbriquées, ce qui fait que
   l&#039;utilisation de sous-chaînes à utilisation unique
   pour rechercher les séquences de caractères
   non-parenthèses est important, lorsqu&#039;il s&#039;applique à
   une chaîne qui n&#039;est pas valide. Par exemple, si on l&#039;applique
   à
   
   <code class="literal">(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()</code>
   
   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 <code class="literal">+</code> et
   <code class="literal">*</code> à tester avant de conclure à
   l&#039;échec.
  </p>
  <p class="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
   
   <code class="literal">(ab(cd)ef)</code>
   
   la valeur de la parenthèse capturante est &quot;<code class="literal">ef</code>&quot;,
   qui est la dernière valeur lue au niveau supérieur. Si de nouvelles
   parenthèses sont ajoutées, par exemple :
   
   <code class="literal">\( ( ( (?&gt;[^()]+) | (?R) )* ) \)</code>
   
   alors la chaîne capturée est &quot;<code class="literal">ab(cd)ef</code>&quot;,
   c&#039;est-à-dire le contenu de la parenthèse capturante
   de plus haut niveau. S&#039;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&#039;il ne
   peut obtenir cette mémoire supplémentaire, il ne fait
   que sauver les 15 premières, car il n&#039;y a pas moyen de
   générer une erreur de mémoire dans le cadre d&#039;une récursivité.
  </p>
  
  <p class="para">
   <code class="literal">(?1)</code>, <code class="literal">(?2)</code> et suivants
   peuvent être également utilisés pour les sous masques récursifs. Il est également
   possible d&#039;utiliser les sous masques nommés : <code class="literal">(?P&gt;foo)</code> ou
   <code class="literal">(?&amp;name)</code>.
  </p>
  <p class="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
   <code class="literal">(sens|respons)e and \1ibility</code>
   trouvera <code class="literal">&quot;sense and sensibility&quot;</code> et 
   <code class="literal">&quot;response and responsibility&quot;</code>, mais pas
   <code class="literal">&quot;sense and responsibility&quot;</code>. Si on utilise plutôt le masque
   <code class="literal">(sens|respons)e and (?1)ibility</code>
   alors, il trouvera <code class="literal">&quot;sense and responsibility&quot;</code> 
   tout comme les deux autres chaînes.
   De telles références doivent, cependant, suivre le sous-masque auquel
   elles se réfèrent.
  </p>
  
  <p class="para">
   La longueur maximale d&#039;un sujet correspond au plus grand nombre positif
   qu&#039;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&#039;espace disponible pour la pile peut limiter la taille du sujet qui peut
   être passé à certains masques.
  </p>
 </div><?php manual_footer($setup); ?>