Регулярное выражение завершает работу Apache из-за ограничений PCRE - PullRequest
2 голосов
/ 01 сентября 2010

В настоящее время я создаю механизм синтаксического анализа bbcode, и я столкнулся с ситуацией, которую я не могу понять самостоятельно.

Дело в том, что я столкнулся с проблемой, подобной этой: Apache / PHP в Windows падает с регулярным выражением

Это означает, что если я сделаю что-то похожее на приведенный ниже пример, Apache аварийно завершит работу из-за того, что число рекурсий достигло 690 (ограничение памяти 1 МБ для PCRE):

$txt = '[b]'.str_repeat('a', 338).'[/b]';  // if I change repeat count to lower value it's ok
$regex = '#\[(?P<attributes>(?P<tag>[a-z0-9_]*?)(?:=.*?|\s.*?|))](?P<content>(?:[^[]|\[(?!/?(?P=tag)])|(?R))+?)\[/(?P=tag)]#mi';

echo preg_replace_callback($regex, function($matches) { return $matches['content']; }, $txt);

Так что мне нужно каким-то образом минимизировать потребность в * и + в моем регулярном выражении, но здесь у меня нет идей, поэтому я подумал, что, может быть, вы могли бы что-то предложить.

Другие подходы для парсинга bbcode (которые могут обрабатывать вложенные теги) приветствуются. Однако я не хотел бы использовать уже построенный класс или что-то. Мне нравится делать вещи самостоятельно!

Я также изучил PECL и Pear HTML_BBCodeParser. Но я не хочу, чтобы мое приложение зависело от расширений. Скорее всего, я могу сделать какой-нибудь скрипт, который проверяет это расширение и, если он не существует, использовать парсер BBCode, который я пытаюсь сделать здесь.

Извините, если мои описания мрачны, я не профессионал в английском ^^

EDIT. Итак, регулярное выражение объяснило:

\[(?P<attributes>(?P<tag>[a-z0-9_]*?)(?:=.*?|\s.*?|))]

Это мой начальный тег. Я использовал именованные группы. С помощью «тега» я идентифицирую тег, а с «атрибутами» - атрибуты тегов. Думайте о теге как об атрибуте. Так что здесь происходит? Я пытаюсь сопоставить тег, когда сопоставляется тег, я пытаюсь сопоставить что-либо после знака = или что-нибудь после \s (пробел), пока не достигнет закрытия тега ].

(?P<content>(?:[^[]|\[(?!/?(?P=tag)])|(?R))+?)

Теперь я пытаюсь сопоставить содержимое. Это сложная часть. Я ищу любой символ, которого нет [и если я его найду, то я проверяю, не является ли он моим конечным тегом или рекурсией, и говорю движку регулярных выражений делать это до тех пор, пока ....

\[/(?P=tag)]

... найден конечный тег.

Ответы [ 2 ]

3 голосов
/ 01 сентября 2010

Ваше регулярное выражение, особенно утверждения нулевой ширины (обход), приводят к тому, что механизм регулярного возврата катастрофически возвращается. Мораль истории: Regex не может не должен использоваться для анализа языков, которые не являются регулярными. Если у вас есть вложенные структуры, это не обычный язык.

На самом деле, я думаю, что BBCode - это зло . BBCode - это язык разметки, изобретенный ленивыми программистами, которые не хотят правильно фильтровать HTML. В результате у нас теперь есть свободный «стандарт», который сложно реализовать. Отфильтруйте ваш HTML правильно:

http://htmlpurifier.org/

2 голосов
/ 01 сентября 2010

Я собирался предложить BBCodeParser ...

Я также изучил PECL и Pear HTML_BBCodeParser.Но я не хочу, чтобы мое приложение зависело от расширений

Я нахожу это очень странным.Зачем изобретать велосипед?Одним из принципов хорошей программной инженерии является СУХОЙ (не повторяй себя).Вы пытаетесь решить проблему, которая уже была решена.

Мне нравится делать вещи самостоятельно!

Это само по себе неплохо, но естьвремена, когда вам лучше использовать проверенное и верное решение;тот, который лучше протестирован и более надежен, чем ваш (как вы выяснили).Таким образом, вы потратите время на проблему, которую вы действительно хотите решить, вместо того, чтобы решить проблему, которая уже была решена.Не попадайтесь в ловушку изобретения колеса.:)

Мое предложение (и решение) для вас состоит в том, чтобы использовать синтаксический анализатор BBCode.

EDIT

Другое дело, что вы анализируетечто-то похожее на HTML.Вещи такого рода не могут быть легко проанализированы с помощью регулярных выражений.

...