Повторение задаётся при помощи квантификаторов, следующих за любым из указанных ниже элементов:
Общий квантификатор повторения указывает минимальное и максимальное
допустимое количество совпадений, согласно двум числам, заключёнными
в фигурные скобки и разделёнными запятой. Числа должны быть меньше чем 65536,
и первое число не должно превышать второе по значению.
Например:
z{2,4}
соответствует «zz», «zzz» или «zzzz». Закрывающая фигурная скобка сама
по себе не является специальным символом. Если второе число опущено,
но запятая присутствует, нет верхнего предела; Если и второе
число и запятая опущены, требуется точное число повторений.
Таким образом
[aeiou]{3,}
соответствует как минимум трём последовательным гласным (а также любому
их количеству выше трёх), в то время как
\d{8}
соответствует ровно восьми цифрам. Открывающая фигурная скобка,
расположенная в недопустимой для квантификатора позиции, либо не
соответствующая синтаксису квантификатора, интерпретируется как
обыкновенная символьная строка. Например, {,6} — не квантификатор,
а интерпретируется как символьная строка из четырёх символов.
Квантификатор {0} является допустимым и ведёт себя таким образом, будто бы сам квантификатор и предшествующий ему элемент отсутствуют.
Для удобства (а так же обратной совместимости) три наиболее распространённых квантификатора имеют односимвольные аббревиатуры:
* |
эквивалентен {0,} |
+ |
эквивалентен {1,} |
? |
эквивалентен {0,1} |
Можно конструировать бесконечные циклы, указав после шаблона, совпадающего
с пустой строкой, квантификатор, не имеющий верхнего предела, например:
(a?)*
Ранние версии Perl и PCRE выдавали ошибку во время компиляции для таких шаблонов. Однако, поскольку бывают случаи, когда подобные шаблоны могли бы быть полезны, была добавлена поддержка таких шаблонов. Но если любое повторение такой подмаски фактически не совпадает ни с какими символами, цикл принудительно прерывается.
По умолчанию, все квантификаторы являются «жадными», это означает, что они
совпадают максимально возможное количество раз (но не более, чем максимально
допустимое количество раз), не приводя к невозможности сопоставления
остальных частей шаблона. Классический пример проблем, которые
могут возникнуть в связи с такой особенностью квантификаторов -
нахождение комментариев в C-программах. Комментарием считается произвольный
текст, находящийся внутри символьных комбинаций /* и */ (при этом, символы
«/» и «*» тоже могут быть частью комментария). Попытка найти комментарии
при помощи шаблона
/\*.*\*/
в строке
/* первый комментарий */ не комментарий /* второй комментарий */
закончится неудачей, поскольку указанный шаблон соответствует всей строке
целиком (из-за жадности квантификатора «*»).
Однако, если сразу же после квантификатора идёт вопросительный знак, он
становится «ленивым» и соответствует минимально допустимому количеству раз.
Таким образом, шаблон
/\*.*?\*/
корректно находит все комментарии языка Си. Указание символа «?» после
квантификатора влияет только на его жадность, и не влияет
на другие свойства. Не нужно путать символ «?»
как квантификатор (ноль либо одно соответствие) и как ограничитель
жадности. Из-за его двойственности можно пользоваться
следующей записью:
\d??\d
,
которая в первую очередь соответствует одной цифре, но также
может соответствовать и двум цифрам, если это необходимо для
соответствия остальных частей шаблона.
Если установлена опция PCRE_UNGREEDY (отсутствующая в Perl), квантификаторы не являются жадными по умолчанию, но могут становиться таковыми, если за ними следует символ «?». Говоря другими словами, знак вопроса инвертирует жадность квантификаторов.
Квантификаторы, за которыми следует +
, являются «захватывающими».
Они поглощают столько символов, сколько могут и не возвращаются обратно
для совпадения остатка шаблона. Таким образом .*abc
совпадёт с «aabc», а .*+abc
— нет, потому что
.*+
захватит всю строку целиком. Захватывающие
квантификаторы могут быть использованы для ускорения обработки.
Если используется подмаска с квантификатором, для которого задано минимальное количество повторений (больше одного), либо задано максимальное количество повторений, то для откомпилированного шаблона требуется больше памяти (пропорционально минимуму либо максимуму соответственно).
Если шаблон начинается с .* либо .{0,} и установлен модификатор PCRE_DOTALL (являющийся аналогом Perl-опции /s), который позволяет метасимволу «точка» соответствовать переводам строк, шаблон неявно заякоривается. Это происходит поскольку все последующие конструкции будут сопоставляться с каждой символьной позицией в обрабатываемом тексте, и, как следствие, начало строки — единственная позиция, дающая наиболее полное совпадение. PCRE рассматривает каждый такой шаблон, как если бы ему предшествовала последовательность \A. Если известно, что данные не содержат переводов строк, а сам шаблон начинается на .*, рекомендуется использовать PCRE_DOTALL для оптимизации шаблона, либо указывать метасимвол «^» для явного заякоривания.
Если захватывающая подмаска повторяется, результирующим значением
подмаски будет подстрока, совпадающая с результатом последней итерации.
Например, после того, как
(tweedle[dume]{3}\s*)+
совпадёт с «tweedledum tweedledee», результирующим значением подмаски
будет «tweedledee». Однако, если присутствуют вложенные захватывающие
подмаски, соответствующие значения могут быть установлены в предыдущих
итерациях. Например, после того, как
/(a|(b))+/
совпадёт с «aba», значением второй захваченной подстроки будет «b».