Повторення

Повторення задається за допомогою квантифікаторів, наступних за будь-яким із наведених нижче елементів:

  • довільним, можливо екранованим символом
  • метасимволом «точка»
  • символьним класом
  • посиланням на попередній фрагмент шаблону (див. наступний розділ)
  • взятої в круглий дужки підмаскою (якщо це не твердження - дивіться далі)

Загальний квантифікатор повторення вказує мінімальну та максимальну допустиму кількість збігів, згідно з двома числами, укладеними у фігурні дужки та розділеними комою. Числа повинні бути меншими ніж 65536, і перше число не повинно перевищувати друге за значенням. Наприклад: z{2,4} відповідає "zz", "zzz" або "zzzz". Фігурна дужка, що закриває, сама по собі не є спеціальним символом. Якщо друге число опущено, але кома присутня, немає верхньої межі; Якщо і друге число і кома опущені, потрібна точна кількість повторень. Таким чином [aeiou]{3,} відповідає як мінімум трьом послідовним голосним (а також будь-якій їх кількості вище трьох), у той час як \d{8} відповідає рівно вісім цифр. Фігурна дужка, що відкриває, розташована в неприпустимій для квантифікатора позиції, або не відповідає синтаксису квантифікатора, інтерпретується як звичайний символьний рядок. Наприклад, {,6} - не квантифікатор, а інтерпретується як символьний рядок із чотирьох символів.

Квантифікатор {0} є допустимим і поводиться таким чином, нібито сам квантифікатор і елемент, що його передує, відсутні.

Для зручності (а також зворотної сумісності) три найбільш поширені квантифікатори мають односимвольні абревіатури:

Односимвольні квантифікатори
*еквівалентний {0,}
+< /code>еквівалентний {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».