Хорошо, PHP не очень разговорчив о ошибках регулярных выражений, он просто возвращает false
для последнего случая, который просто говорит, чем произошла ошибка, за PHP docs.
Я воспроизвел проблему, используя PCRE (двигатель регулярных выражений, используемый preg_match
) в C# (но с гораздо большим количеством символов), а ошибка, которую я получаю, - PCRE_ERROR_MATCHLIMIT
.
Это означает, что вы нажимаете ограничение на возврат, установленное в PCRE. Это всего лишь мера безопасности, чтобы предотвратить зависание двигателя на неопределенный срок, и я думаю, что ваша конфигурация PHP устанавливает его на низкое значение.
Чтобы устранить эту проблему, вы можете установить более высокое значение параметра pcre.backtrack_limit
PHP, который контролирует этот предел:
ini_set("pcre.backtrack_limit", "10000000"); // Actually, this is PCRE's default
На стороне записки:
- Вы, вероятно, следует заменить
(.*)
с (.*?)
чтобы получить меньше бесполезного возврата и для правильности (иначе двигатель регулярного выражения пройдет мимо строки STOP
и должен будет вернуться к нему)
- Использование
?
в качестве разделителя шаблона является идеей bad, так как это предотвращает использование метасимвола ?
и, следовательно, применение вышеуказанного совета. Действительно, вы должны никогда использовать метасимволы регулярных выражений как разделители шаблонов.
Если вы заинтересованы в деталях более низкого уровня, вот соответствующий бит PCRE DOCS (курсив мой):
Поле match_limit
обеспечивает средство предотвращения PCRE от используя огромное количество ресурсов при запуске шаблонов, которые не будут соответствовать, но которые имеют очень большое количество возможностей в деревьях поиска. Классическим примером является шаблон, который использует вложенные неограниченные повторы.
Внутренне, pcre_exec()
использует функцию, называемую match()
, которую он вызывает многократно (иногда рекурсивно).Предел, установленный на match_limit
, накладывается на количество вызов этой функции во время совпадения, , что приводит к ограничению суммы обратного отслеживания, которое может иметь место. Для шаблонов, которые не привязаны, число отсчитывается от нуля для каждой позиции в строке темы.
Когда pcre_exec()
вызывается с шаблоном, который был успешно изучен с помощью опции JIT, способ выполнения сопоставления совершенно другой. Тем не менее, по-прежнему существует возможность совпадения убегания, которое продолжается очень долгое время, поэтому значение match_limit
также используется в этом случае (но по-другому), чтобы ограничить продолжительность продолжения сопоставления.
Значение по умолчанию для предела может быть установлено при построении PCRE; по умолчанию по умолчанию - 10 миллионов, который обрабатывает все, кроме самых экстремальных случаев. Вы можете переопределить значение по умолчанию, добавив pcre_exec()
с блоком pcre_extra
, в котором установлено match_limit
, а PCRE_EXTRA_MATCH_LIMIT
установлено в поле flags. Если предел превышен, pcre_exec()
возвращает PCRE_ERROR_MATCHLIMIT
.
Значение предела для соответствия также может быть поставлено элементом в начале шаблона формы
(*LIMIT_MATCH=d)
, где d
это десятичное число. Однако такой параметр игнорируется, если d не меньше предела, установленного вызывающим абонентом pcre_exec()
, или, если такой лимит не установлен, меньше, чем значение по умолчанию.
Вы достигли предела памяти; попробуйте увеличить его в своем 'PHP.ini' –