В настоящее время я создаю механизм синтаксического анализа 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, который я пытаюсь сделать здесь.
Извините, если мои описания мрачные, я не профи в английском ^^
РЕДАКТИРОВАТЬ. Итак, регулярное выражение объяснило:
\[(?P<attributes>(?P<tag>[a-z0-9_]*?)(?:=.*?|\s.*?|))]
Это мой открывающий тег. Я использовал именованные группы. С помощью «тега» я идентифицирую тег, а с помощью «атрибутов» я идентифицирую атрибуты тегов. Думайте о теге как об атрибуте. Так что же здесь происходит? Я пытаюсь сопоставить тег, когда тег сопоставляется, я пытаюсь сопоставить что-либо после знака =
или что-либо после \s
(пробел), пока не будет достигнуто закрытие тега ]
.
(?P<content>(?:[^[]|\[(?!/?(?P=tag)])|(?R))+?)
Теперь здесь я пытаюсь соответствовать содержанию. Это сложная часть. Я ищу любой символ, который не является [, и если я нахожу его, я проверяю, не является ли он моим конечным тегом или рекурсией, и я говорю обработчику регулярных выражений делать это, пока....
\[/(?P=tag)]
... конечный тег найден.
I like to do things on my own!
- почему так? Вы также пишете свой собственный движок регулярных выражений? Или ваш собственный интерпретатор/среда выполнения php? - person VolkerK   schedule 01.09.2010