Новичок
Покинул форум
Сообщений всего: 41
Дата рег-ции: Май 2011
Помог: 0 раз(а)
|
Подниму проблему написания bbcode парсера
Введение:
Итак написать парсер не составляет ничего сложного
пример кода
парсер
CODE ( htmlphp):
скопировать код в буфер обмена
<?php class bbcodeSimple { // массив стандартных тегов static $bb = array( # x5 столбцов # Флаги #первый тег #между тегами #закрывающий #Замена 'si', 'b', '(.+)', '/b', '<b>$1</b>', 'si', 'u', '(.+)', '/u', '<u>$1</u>', 'si', 'i', '(.+)', '/i', '<i>$1</i>', ); // функция парсер function parse($text) { for ($i = 0; $i<count(self::$bb); $i+=5) { $text = preg_replace('#\['.self::$bb[$i+1].'\]'.self::$bb[$i+2].'\['.self::$bb[$i+3].'\]#'.self::$bb[$i],self::$bb[$i+4],$text); } // чистка неверных тегов return $text; } } // end class $text = '[b]hello world[/b] [i]привет[/i]'; echo bbcodeSimple::parse($text);
Результат работы кода:
Цитата:<b>hello world</b> <i>привет</i>
САБЖ:
Теперь вернемся к теме и попробуем распарсить вот такой bbcode:
Результат работы кода:
Цитата:<b>helloпривет world</b>
Неправильно! Парсер не смог справиться с задачей!
Верный вариант должен быть вот таким:
Цитата:<b>hello<b>привет</b> world</b>
Ошибка в работе произошла по вине функции preg_replace которая не умеет разбирать вложенные выражения
напишем функцию которая умеет разбирать вложенные выражения
PHP:
скопировать код в буфер обмена
function preg_replace_recursive($pattern, $replace, $subject) { $c = 1; $ret = $subject; while ($c>0) { } return $ret; }
Перепишем класс bbcodeSimple с новой функцией рекурсивного разбора выражений
PHP:
скопировать код в буфер обмена
<?PHP function preg_replace_recursive($pattern, $replace, $subject) { $c = 1; $ret = $subject; while ($c>0) { } return $ret; } class bbcodeSimple { // массив стандартных тегов static $bb = array( # x5 столбцов # Флаги #первый тег #между тегами #закрывающий #Замена 'si', 'b', '(.+)', '/b', '<b>$1</b>', 'si', 'u', '(.+)', '/u', '<u>$1</u>', 'si', 'i', '(.+)', '/i', '<i>$1</i>', ); // функция парсер function parse($text) { for ($i = 0; $i<count(self::$bb); $i+=5) { // << новая функция $text = preg_replace_recursive('#\['.self::$bb[$i+1].'\]'.self::$bb[$i+2].'\['.self::$bb[$i+3].'\]#'.self::$bb[$i],self::$bb[$i+4],$text); } // чистка неверных тегов return $text; } } // end class $text = '[b]hello[b]привет[/b] world[/b]'; echo bbcodeSimple::parse($text);
результат:
Цитата:<b>hello<b>привет</b> world</b>
Вывод:
Функция preg_replace_recursive теперь позволяет написать bbcode парсер на чистых регуляках, без написания классов "конечных автоматов" и прочих тяжеловесных абстракций
Также теперь доступен разбор вложенных тегов, как например теги цитат, используя этот же самый метод
|