<?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 => 'ru',
  ),
  'this' => 
  array (
    0 => 'regexp.reference.repetition.php',
    1 => 'Повторение',
    2 => 'Повторение',
  ),
  'up' => 
  array (
    0 => 'reference.pcre.pattern.syntax.php',
    1 => 'Синтаксис регулярных выражений',
  ),
  'prev' => 
  array (
    0 => 'regexp.reference.subpatterns.php',
    1 => 'Подшаблоны',
  ),
  'next' => 
  array (
    0 => 'regexp.reference.back-references.php',
    1 => 'Обратные ссылки',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ru',
    '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.repetition" class="section">
  <h2 class="title">Повторение</h2>
  <p class="para">
   Повторение определяется квантификаторами, которые идут за любым из указанных
   элементов:
   <ul class="itemizedlist">
    <li class="listitem"><span class="simpara">одним символом, возможно, экранированным</span></li>
    <li class="listitem"><span class="simpara">метасимволом «точка»</span></li>
    <li class="listitem"><span class="simpara">символьным классом</span></li>
    <li class="listitem"><span class="simpara">ссылкой на предыдущий фрагмент шаблона (смотрите следующий раздел)</span></li>
    <li class="listitem"><span class="simpara">взятым в круглые скобки подшаблоном (если это не утверждение — смотрите далее)</span></li>
   </ul>
  </p>
  <p class="para">
   Общий квантификатор повторения указывает минимальное и максимальное
   допустимое количество совпадений, согласно двум числам
   в фигурных скобках, разделённым запятой. Числа должны быть меньше чем 65 536,
   и первое число не должно превышать второе по значению.
   Например:

   <code class="literal">z{2,4}</code>

   соответствует «zz», «zzz» или «zzzz». Закрывающая фигурная скобка сама
   по себе — не специальный символ. Если второе число опустили,
   но запятую поставили, нет верхнего предела; Если и второе
   число, и запятую опустили, требуется точное число повторений.
   Поэтому шаблон

   <code class="literal">[aeiou]{3,}</code>

   соответствует как минимум трём последовательным гласным, а также любому
   количеству гласных выше трёх, тогда как шаблон

   <code class="literal">\d{8}</code>

   соответствует ровно восьми цифрам.
  </p>
  <p class="simpara">
   До PHP 8.4.0 открывающая фигурная скобка, которая появляется в месте,
   где квантификатор не допускается или которая не соответствует синтаксису квантификатора,
   рассматривается как литеральный символ.
   Например, <code class="literal">{,6}</code> не является квантификатором,
   а представляет собой литеральную строку из четырёх символов.

   Начиная с PHP 8.4.0, модуль PCRE поставляется в комплекте с PCRE2 версии 10.44,
   которое допускает такие шаблоны, как <code class="literal">\d{,8}</code>
   и они интерпретируются как <code class="literal">\d{0,8}</code>.

   Кроме того, начиная с PHP 8.4.0, допускаются пробелы вокруг квантификаторов,
   такие как <code class="literal">\d{0 , 8}</code> и <code class="literal">\d{ 0 , 8 }</code>.
  </p>
  <p class="para">
   Квантификатор {0} — допустим и ведёт себя таким образом, будто бы
   сам квантификатор и предшествующий ему элемент отсутствуют.
  </p>
  <p class="para">
   Для удобства, а так же обратной совместимости, у трёх наиболее распространённых
   квантификатора односимвольные аббревиатуры:
   <table class="doctable table">
    <caption><strong>Односимвольные квантификаторы</strong></caption>
    
     <tbody class="tbody">
      <tr>
       <td><code class="literal">*</code></td>
       <td>эквивалентен <code class="literal">{0,}</code></td>
      </tr>

      <tr>
       <td><code class="literal">+</code></td>
       <td>эквивалентен <code class="literal">{1,}</code></td>
      </tr>

      <tr>
       <td><code class="literal">?</code></td>
       <td>эквивалентен <code class="literal">{0,1}</code></td>
      </tr>

     </tbody>
    
   </table>

  </p>
  <p class="para">
   Можно конструировать бесконечные циклы, указав после шаблона, который совпадает
   с пустой строкой, квантификатор без верхнего предела, например:
   <code class="literal">(a?)*</code>
  </p>
  <p class="para">
   Ранние версии языка Perl и модуля PCRE выдавали ошибку во время компиляции для таких
   шаблонов. Однако, поскольку бывают случаи, когда подобные шаблоны могли бы
   быть полезны, была добавлена поддержка таких шаблонов. Но если любое повторение
   такого подшаблона фактически не совпадает ни с какими символами, цикл
   принудительно прерывается.
  </p>
  <p class="para">
   По умолчанию все квантификаторы — «жадные», это означает, что они
   совпадают максимально возможное количество раз (но не более, чем максимально
   допустимое), и не останавливают сопоставление
   остальных частей шаблона. Классический пример проблем, которые
   могут возникнуть в связи с такой особенностью квантификаторов, —
   попытка найти комментарии в программах, которые написали на языке C.
   Комментарием признаётся произвольный текст внутри символьных комбинаций /* и */
   (при этом, символы «/» и «*» тоже могут быть частью комментария). Попытка найти комментарии
   через шаблон

   <code class="literal">/\*.*\*/</code>

   в строке

   <code class="literal">/* первый комментарий */ не комментарий /* второй комментарий */</code>

   закончится неудачей, поскольку указанный шаблон соответствует всей строке
   целиком (из-за жадности квантификатора «*»).
  </p>
  <p class="para">
   Однако, если сразу же после квантификатора идёт вопросительный знак, квантификатор
   становится «ленивым» и соответствует минимально допустимому количеству раз.
   Поэтому шаблон

   <code class="literal">/\*.*?\*/</code>

   корректно находит комментарии языка C. Знак «?» после
   квантификатора влияет только на его жадность, и не влияет
   на другие свойства. Не нужно путать
   квантификатор «?» (ноль или одно соответствие) ограничитель
   жадности. Из-за его двойственности пользуются
   следующей записью:

   <code class="literal">\d??\d</code>,

   которая, в первую очередь, соответствует одной цифре, но также
   может соответствовать и двум цифрам, если это необходимо для
   соответствия остальных частей шаблона.
  </p>
  <p class="para">
   Если установили опцию
   <a href="reference.pcre.pattern.modifiers.php" class="link">PCRE_UNGREEDY</a>
   (которой нет в языке Perl), квантификаторы перестают быть жадными по умолчанию,
   но могут становиться жадными, если за ними идёт символ «?».
   Говоря другими словами, знак вопроса инвертирует жадность
   квантификаторов.
  </p>
  <p class="para">
   Квантификаторы, за которыми идёт символ <code class="literal">+</code>, — «захватывающие».
   Они поглощают столько символов, сколько могут, и не возвращаются обратно
   для совпадения остатка шаблона. Поэтому шаблон <code class="literal">.*abc</code>
   совпадёт с «aabc», а <code class="literal">.*+abc</code> — нет, потому что
   подшаблон <code class="literal">.*+</code> захватит всю строку целиком. Захватывающими
   квантификаторами пользуются для ускорения обработки.
  </p>
  <p class="para">
   Если задали подшаблон с квантификатором, для которого установили минимальное
   количество повторений (больше одного), либо задали максимальное количество
   повторений, то для откомпилированного шаблона требуется больше памяти
   (пропорционально минимуму либо максимуму соответственно).
  </p>
  <p class="para">
   Если шаблон начинается с символов .* либо .{0,} и установили модификатор
   <a href="reference.pcre.pattern.modifiers.php" class="link">PCRE_DOTALL</a>
   (аналог Perl-опции /s), который разрешает метасимволу
   «точка» соответствовать переводам строк, шаблон неявно заякоривается.
   Это происходит потому, что все последующие конструкции парсер будет сопоставлять
   с каждой символьной позицией в обрабатываемом тексте, и, как следствие,
   начало строки — единственная позиция, которая даёт наиболее полное совпадение.
   Модуль PCRE рассматривает каждый такой шаблон, как если бы ему предшествовала
   последовательность \A. Если известно, что данные
   не содержат переводов строк, а сам шаблон начинается с символов .*, рекомендуется
   использовать модификатор <a href="reference.pcre.pattern.modifiers.php" class="link">PCRE_DOTALL</a>
   для оптимизации шаблона, либо указывать метасимвол «^» для явного заякоривания.
  </p>
  <p class="para">
   Если захватывающий подшаблон повторяется, результирующим значением
   подшаблона будет подстрока, которая совпадает с результатом последней итерации.
   Например, когда шаблон

   <code class="literal">(tweedle[dume]{3}\s*)+</code>

   совпадёт со значением «tweedledum tweedledee», результирующим значением подшаблона
   будет значение «tweedledee». Однако, если присутствуют вложенные захватывающие
   подшаблоны, значения, которые соответствуют этим подшаблонам, допускается устанавливать
   в предыдущих итерациях. Например, когда шаблон

   <code class="literal">/(a|(b))+/</code>

   совпадёт со значением «aba», значением второй захваченной подстроки будет значение «b».
  </p>
 </div><?php manual_footer($setup); ?>