Я работаю над относительно сложным и очень большим регулярным выражением. В настоящее время он составляет 41 127 символов и может несколько увеличиться по мере добавления дополнительных случаев. Я начинаю получать эту ошибку в PHP:
preg_match_all (): Ошибка компиляции: регулярное выражение слишком велико при смещении 41123
Есть ли способ увеличить размер? Следующие настройки, рекомендованные в других местах, НЕ работали, потому что они относятся к размеру данных и NOT размер регулярного выражения:
ini_set("pcre.backtrack_limit", "100000000"); ini_set("pcre.recursion_limit", "100000000");
Альтернативно, существует ли способ определить «переменную подматрицы» в регулярном выражении, которая может повторяться в разных местах регулярного выражения? (Я не говорю о повторении, используя *
или +
, или даже повторяя соответствие «1»)? Я фактически использую переменные PHP, содержащие подматрицы, которые повторяются в нескольких местах в регулярном выражении, но это приводит к расширению регулярного выражения до того, как оно передается в функции PRCE.
Это сложное регулярное выражение и не может быть заменено более простым поиском ключевого слова с использованием strpos
или подобным, как предлагается по этой ссылке .
Я бы предпочел не разбивать это на подвыражения в |
и пытается сопоставить подвыражения отдельно, потому что уменьшение размера будет скромным (всего 2 или 3 уровня верхнего уровня), что осложнит дальнейшее развитие.
Я не согласен с комментариями, что может быть лучший способ сделать это, но я отвечу на этот вопрос.
Вы можете увеличить максимальный размер регулярного выражения, но только путем перекомпиляции PHP самостоятельно. Из-за этого ваш код совсем не переносится, и если вы используете предварительно скомпилированные двоичные файлы, вам не повезло.
Тем не менее, я бы предложил найти альтернативу для сопоставления.
См. Pcre_internal.h для комментариев.
PCRE сохраняет смещения в сводном коде в виде 2-байтовых величин (всегда хранящихся в ординарном порядке) по умолчанию. Они используются, например, для привязки с начала подшаблона к его альтернативам и его концу. Использование 2 байтов на смещение ограничивает размер скомпилированного регулярного выражения примерно до 64 КБ, что достаточно для почти всех. Тем не менее, я получил запрос на еще больший предел. По этой причине, а также для упрощения обслуживания кода сохранение и загрузка смещений из строки байтов теперь обрабатываются макросами, которые определены здесь.
Макросы управляются значением LINK_SIZE. Это значение по умолчанию равно 2 в файле config.h, но может быть переопределено с помощью -D в командной строке. Это автоматизировано в Unix-системах с помощью команды «configure».
Таким образом, вы можете либо отредактировать ext/pcre/pcrelib/config.h
из исходного источника PHP, чтобы увеличить ограничение по размеру, либо указать его при компиляции ./configure -DLINK_SIZE=4
EDIT: если вы пытаетесь совместить / разбирать HTML, я бы рекомендовал использовать DOMDocument для анализа HTML-кода, а затем пройти дерево DOM или создать XPATH, чтобы найти то, что вы ищете.
В зависимости от приложения действительными решениями являются:
|
и обрабатывать полученные подвыражения отдельно. Если регулярное выражение представляет собой по существу множество ключевых слов, разделенных символом |
, то преобразование в strtok или цикл с strpos может быть лучшим и быстрым выбором. Решение моей конкретной проблемы: согласно комментарию Марио, используя конструкцию (?(DEFINE)...)
для некоторых подвыражений, которые были повторно использованы несколько раз, уменьшил размер моего регулярного выражения с 41 127 символов до «всего» 4,071 , и это было изящное решение, чтобы избавиться от ошибки «Регулярное выражение слишком велико».
См.: (? (DEFINE) …) ссылка на синтаксис rexegg.com