Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Парсинг BBcode (https://javascript.ru/forum/misc/24939-parsing-bbcode.html)

Gozar 19.01.2012 17:41

Парсинг BBcode
 
Пишу сейчас, вернее уже дописываю парсинг BBcode регой.

Вид реги не имеет значения, суть такова:

Текст
[B]aaaa [B] bbbb[/B] aaa[/B]
парсится регой так:
Сначала находиться:
[B] bbbb[/B]
, затем нужно рекурсивно вызвать регу снова и она найдет:
[B]aaaa <b> bbbb</b> aaa[/B]


Меня всё устраивает, но выглядит идея как-то громоздко, хотя сохраняется вложенность, если таковая имеется и всякие там [color = red\]bububu[/color] не проблема, ведь мы получаем весь BBcode и можем потом с ним делать что хотим.

Раньше парсил быстрее, но раздельно начало и конец, но решение получалось какое-то заумное и разрозненное.

Есть идеи как можно быстрее парсить BBcode, нежели рекурсией?

ps: По BBcode-ам проходим циклом, b,u,i,s,img ...

Gozar 19.01.2012 17:49

Или может быть как-то отпарсить текст в стек, какой-нибудь универсальной регой, а затем уже с ним работать?
Однако опять не понятно что делать с вложенностью.

Gozar 19.01.2012 17:53

Просьба не давать ссылки на гугл, особенно если вы сами не работали с кодом и скриптами предлагаемыми там.

devote 19.01.2012 18:10

ну у меня только такой в голову вариант пока что пришел.
var text = 'test [b]bold[/b] blah [code]function(){}[/code] tar [quote]blah blah [i]ta[i]r[/i]am[/i] param[/quote]';

function parseBBCode( text ) {
    return text.replace( /\[(([a-z]+)(?:\=[^\]]+)?)\](.*)\[\/\2\]/gi, function( all, tag, tagAttr, content ) {
        return '<' + tagAttr + '>' + parseBBCode( content ) + '</' + tagAttr + '>';
    });
}

alert( parseBBCode( text ) );

devote 19.01.2012 18:25

можно сделать и так:
var text = 'test [b=color]bold[/b] blah [code run]function(){}[/code] tar [quote]blah blah [i]ta[i]r[/i]am[/i] param[/quote]';
 
function parseBBCode( text ) {
    return text.replace( /\[(([a-z]+)(?:(?:\=|\s)([^\]]+))?)\](.*)\[\/\2\]/gi, function( all, tagAttr, tag, attr, content ) {

        // tag - содержит имя тега BBCode
        // tagAttr - содержит и тег и его атрибут(ы)
        // attr - трибут(ы) текущего тега
        // content - собственно содержимое этого тега

        return '<' + tagAttr + '>' + parseBBCode( content ) + '</' + tag + '>';
    });
}
 
alert( parseBBCode( text ) );


BBCode теги он ищет такого вида:
[code]
[code=color]
[code run]
[code run hide]

Ну а дальше дело техники и воображения.

Gozar 19.01.2012 19:04

Понял, берем по максимуму и затем ужимаем, у меня брало по минимуму.

devote 19.01.2012 19:29

Хотя в том варианте у меня плохо обрабатывал он такой вариант:
test [b=color]bold[/b] tatata [b]blah[/b] tata

можно сделать немного иначе, сначала обработать не жадным методом, а на последок жадным, тем самым мы обработаем все теги корректно.

var text = 'test [b=color]bold[/b] tatata [b]blah[/b] [code run]function(){}[/code] tar [quote]blah blah [i]ta[i]r[/i]am[/i] param[/quote]';
  
function parseBBCode( text, greed ) {
    var re = new RegExp("\\[(([a-z]+)(?:(?:\\=|\\s)([^\\]]+))?)\\](.*" + ( greed ? '' : '?' ) + ")\\[\\/\\2\\]", "gi");
    return text.replace( re, function( all, tagAttr, tag, attr, content ) {
 
        // tag - содержит имя тега BBCode
        // tagAttr - содержит и тег и его атрибут(ы)
        // attr - трибут(ы) текущего тега
        // content - собственно содержимое этого тега

        return '<' + tagAttr + '>' + parseBBCode( content, greed ) + '</' + tag + '>';
    });
}
  
alert( parseBBCode( parseBBCode( text ), true ) );


в реге вместо [a-z]+ можно написать только разрешенные теги, типа:
b|i|u|img|code

Gozar 19.01.2012 19:46

Цитата:

Сообщение от devote (Сообщение 151490)
Хотя в том варианте у меня плохо обрабатывал он такой вариант:

В каком? Не понял.

Цитата:

Сообщение от devote (Сообщение 151490)
в реге вместо [a-z]+ можно написать только разрешенные теги, типа:
b|i|u|img|code

Думаю не нужно, я проверяю уже когда в функцию прилетает выбранный кусок, так работать должно быстрее.

devote 19.01.2012 19:47

Цитата:

Сообщение от Gozar
В каком?

в первых двух
Цитата:

Сообщение от Gozar
Думаю не нужно, я проверяю уже когда в функцию прилетает выбранный кусок, так работать должно быстрее.

дело выбора :) как тебе удобнее конечно, с другой стороны твое решение и возможностей больше даст

Gozar 19.01.2012 19:53

Цитата:

Сообщение от devote (Сообщение 151496)
в первых двух

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


Часовой пояс GMT +3, время: 16:59.