Повторення
Повторення задається за допомогою квантифікаторів, наступних за будь-яким із наведених нижче елементів:
- довільним, можливо екранованим символом
- метасимволом «точка»
- символьним класом
- посиланням на попередній фрагмент шаблону (див. наступний розділ)
- взятої в круглий дужки підмаскою (якщо це не твердження - дивіться далі)
Загальний квантифікатор повторення вказує мінімальну та максимальну допустиму кількість збігів, згідно з двома числами, укладеними у фігурні дужки та розділеними комою. Числа повинні бути меншими ніж 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».