Продуктивність

Деякі елементи, які можуть зустрічатися в шаблонах, є більш ефективними, ніж інші. Наприклад, набагато ефективніше використовувати символьний клас [aeiou] замість набору альтернатив (a|e|i|o|u). Як правило, простіша конструкція є більш ефективною. Книга Джеффрі Фрідла містить багато обговорень щодо оптимізації регулярних виразів.

Якщо шаблон починається з .* та використовується прапор PCRE_DOTALL, шаблон неявно заякорюється, оскільки він може збігатися лише на початку рядка. Але якщо PCRE_DOTALL не використовується, PCRE не може виконати відповідну оптимізацію, так як У цій ситуації метасимвол «.» не відповідає символу початку рядка (якщо дані, що обробляються, містять переклади рядків, такий шаблон може відповідати шаблону не від початку рядка, а від позиції безпосередньо після перекладу рядка). Наприклад, застосовуючи шаблон (.*) secondк строке «first\nand second» (где\n означає символ перекладу рядка), значення, захоплене першою підмаскою, буде «and». Щоб обробити всі можливі точки відповідності, PCRE намагається зіставити шаблон після кожного символу перекладу рядка.

Якщо ви використовуєте подібні шаблони для обробки даних, що не містять перекладів рядків, для кращої продуктивності використовуйте модифікатор PCRE_DOTALLабо починайте шаблон з ^.* для вказівки явного заякорювання. Це запобігатиме PCRE від пошуку символів нових рядків і додаткових спроб зіставити шаблон з кожною такою знайденою позицією.

Уникайте шаблонів, які містять вкладені необмежені повторення. Зіставлення їх із рядками, які містять збігів, займає тривалий час. Розглянемо приклад шаблону (a+)*

Він може відповідати «aaaa» тридцятьма трьома у різний спосіб, і ця цифра дуже швидко зростає при збільшенні рядка. (У цьому прикладі, квантифікатор * може збігатися 0, 1, 2, 3 або 4 рази, і для кожного такого випадку, крім нуля, квантифікатор + також може збігатися різне число разів.) Якщо залишок шаблону такий, що весь збіг зазнає невдачі, PCRE має спробувати всі можливі варіанти збігу що може вимагати величезної кількості часу.

За допомогою оптимізації можна відловити найпростіші випадки, такі як (a+)*b де слідом йде літеральний символ. Перш, ніж проводити стандартну процедуру пошуку, PCRE перевіряє у наступному підрядку наявність символу «b», і, у разі відсутності такого, спроба зіставлення негайно завершується невдачею. Однак, коли наступного літералу немає, оптимізація не може бути застосована. Ви можете відчути різницю, порівнявши поведінку (a+)*\d з поведінкою наведеного вище шаблону. Перший визначає неможливість зіставлення практично відразу ж, при порівнянні зі рядком, що складається з символів «a», тоді як другий витрачає тривалий час на пошук у рядках довше 20 символів.