> Beware of patterns that contain nested indefinite repeats. These can take a long time to run when applied to a string that does not match.
To say that it takes a "long time" is an understatement: the time taken would be exponential, specifically 2^n, where n is the number of "a" characters. This behavior could lead to a "regular expression denial of service" (ReDoS) if you run such a expression on user-provided input.
To not be hit by ReDoS, do one (or maybe more than one) of the three things:
* Write your expression so that it is not vulnerable. https://www.regular-expressions.info/redos.html is a good resource (both the "atomic" and "possessive" options are available in PHP/PCRE). Use a "ReDoS detector" or "regex linter" if your eyeballs can't catch all the issues.
* Set up some limits for preg_match. Use `ini_set(...)` on the values mentioned on https://www.php.net/manual/en/pcre.configuration.php. Reducing the limits might cause regexes to fail, but that is usually better than stalling your whole server.
* Use a different regex implementation. There used to be an RE2 extension; not any more!Оваа функција е достапна кога PHP е поврзан со библиотеки на Oracle Database од верзија 10
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
Оваа функција е достапна кога PHP е поврзан со библиотеки на Oracle Database од верзија 10
Референца за `regexp.reference.performance.php` со подобрена типографија и навигација.
Оваа функција е достапна кога PHP е поврзан со библиотеки на Oracle Database од верзија 10
Одредени ставки што може да се појават во обрасци се поефикасни од други. Поефикасно е да се користи класа на знаци како [aeiou] отколку сет од алтернативи како (a|e|i|o|u). Општо земено, наједноставната конструкција што го обезбедува потребното однесување обично е најефикасна. Книгата на Џефри Фридл содржи многу дискусии за оптимизирање на регуларните изрази за ефикасни перформанси.
Кога образецот започнува со .* и PCRE_DOTALL опцијата е поставена, образецот е имплицитно закотвен од PCRE, бидејќи може да се совпадне само на почетокот на тематскиот стринг. Сепак, ако
PCRE_DOTALL
не е поставено, PCRE не може да ја направи оваа оптимизација, бидејќи мета-знакот . тогаш не се совпаѓа со нов ред, и ако тематскиот стринг содржи нови редови, образецот може да се совпадне од знакот непосредно по еден од нив наместо од самиот почеток. На пример, образецот
(.*) second
се совпаѓа со темата "first\nand second" (каде \n означува знак за нов ред) со првата зафатена подниза што е "and". За да го стори ова, PCRE мора да го повтори совпаѓањето почнувајќи по секој нов ред во темата.
Ако користите таков образец со тематски стрингови што не содржат нови редови, најдобрата изведба се добива со поставување PCRE_DOTALL, или започнување на образецот со ^.* за да се означи експлицитно закотвување. Тоа го спасува PCRE од потребата да го скенира тематскиот стринг барајќи нов ред за повторно стартување.
Внимавајте на обрасците што содржат вгнездени неопределени повторувања. Овие можат да потраат долго време кога се применуваат на стринг што не се совпаѓа. Разгледајте го фрагментот од образецот
(a+)*
Ова може да се совпадне со "aaaa" на 33 различни начини, и овој број се зголемува многу брзо како што стринг станува подолг. (Повторувањето * може да се совпадне 0, 1, 2, 3 или 4 пати, и за секој од тие случаи освен 0, повторувањата + можат да се совпаднат со различен број пати.) Кога остатокот од образецот е таков што целото совпаѓање ќе пропадне, PCRE во принцип мора да ги испроба сите можни варијации, и ова може да потрае исклучително долго време.
Оптимизацијата фаќа некои од поедноставните случаи како
(a+)*b
каде што следи литерален знак. Пред да се впушти во стандардната процедура за совпаѓање, PCRE проверува дали постои "b" подоцна во тематскиот стринг, и ако не постои, веднаш го откажува совпаѓањето. Сепак, кога нема следен литерал, оваа оптимизација не може да се користи. Можете да ја видите разликата споредувајќи го однесувањето на
(a+)*\d
со горниот образец. Првиот дава неуспех речиси веднаш кога се применува на цел ред од "a" знаци, додека вториот трае забележливо време со стрингови подолги од околу 20 знаци.