- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
Example #3 preg_replace_callback() using recursive structure to handle encapsulated BB code
<?php
$input = "plain [indent] deep [indent] deeper [/indent] deep [/indent] plain";
function parseTagsRecursive($input)
{
$regex = '#\[indent]((?:[^[]|\[(?!/?indent])|(?R))+)\[/indent]#';
if (is_array($input)) {
$input = '<div style="margin-left: 10px">'.$input[1].'</div>';
}
return preg_replace_callback($regex, 'parseTagsRecursive', $input);
}
$output = parseTagsRecursive($input);
echo $output;
?>
Не знаю, баян или нет. Поиском не смог найти preg_replace_callback на этом сайте.
В таком недлинном коде есть очень аппетитное дерьмецо (кроме языка). Если в качестве $input взять строку подлиннее, то интерпретатор, как Чак Норрис, сосчитает до бесконечности. Исправляется добавлением одного символа к коду.
3.14159265 04.07.2011 16:53 # 0
inkanus-gray 04.07.2011 19:51 # +1
Спойлер: Убийца — дворецкий. Если добавить плюсик после первой альтернативы, то зацикливание внезапно исчезает: (?:[^[]+|(?R))+
Можете кидать в меня камни. Пример взят с php.net из документации по упомянутой функции. О том, к чему приводит подобный код, ни на одной странице ни слова. Короче, входная строка сопоставляется с (?R) и происходит рекурсивный вызов на каждом символе строки, что приводит к аду уже когда длина входной строки около сотни символов.