У меня есть функции preg_match_all с шаблоном:
preg_match_all(
'/\[(if) ([^\]]*)\]
((?:(?!\[if).|(?R))*?)
\[endif\]/sx',
$text,
$matches
);
Это довольно простой шаблон, я думаю, он ищет синтаксис [if condition] sometext [endif]
, но он также поддерживает встраивание ifs f.e. [if condition1] aa [if condition2] bb [endif] [endif]
, Я использовал переключатель s, чтобы рассматривать новые строки как точки (поскольку я хочу, чтобы они работали многострочно), а x — для более удобного чтения (но удаление x не решает проблему).
Он отлично работает для большинства входных данных, которые у меня есть, но для некоторых конкретных входных данных он вызывает ошибку 502 Bad gateway на сервере nginx без каких-либо ошибок или исключений в журналах. Я использую nginx + php-fpm (5.6.15-1 + deb.sury.org ~ trusty + 1), но то же самое происходит на php7.
Вот причина ошибки 502 Плохой шлюз PHP-кода, который вы можете легко проверить, очень просто, просто переменная и регулярное выражение.
Пожалуйста, убедитесь, что вы скопировали контент 1: 1 со всеми пробелами, вкладками и т. Д.
Очень странно то, что вы можете удалить практически любую отдельную строку или даже удалить один отступ (несколько пробелов в любом месте), чтобы он работал.
У меня больше нет идей, что здесь не так, я смог создать этот единственный файл, чтобы продемонстрировать свою проблему, но не знаю, как ее исправить.
Ваше регулярное выражение содержит негативную перспективу, которая «смягчает» шаблон точек. Однако вы не смогли добавить к нему конечный разделитель, и он стал довольно «тяжелым».
Я предлагаю добавить конечный разделитель ([endif]
) к проверке:
\[(if)\s+([^\]]*+)\]((?>(?!\[(?:end)?if\b).|(?R))*)\[endif\]
^^^^^^^^
Увидеть демонстрация
Или вы можете даже развернуть закаленный жадный жетон как
\[(if)\s+([^\]]*+)\]((?>[^[]++(?:\[(?!(?:end)?if\b)[^[]*)*|(?R))*)\[endif\]
Увидеть регулярное выражение демо (однако, если [
может следовать [if...]
это не сработает)
Также, нота что у вашего регулярного выражения есть пробел после (if)
и так как вы используете /x
Модификатор, он не считается буквальным пространством, но игнорируется. Вот почему я изменил его на \s+
,
Других решений пока нет …