Цитата:
|
да, что-то более лучшего ничего не выходит, только так:
var text = 'test [b]blah [i]tata[/i] blah[/b] param [quote="test"]lal[alala[/quote] qweqweqwe [u]ter[u]tet[/u]er[/u] hjf [u]sdhg[/u] end'; var re = /(\[\s*([a-z]+)\s*(?:=?\s*([^\]]+))?\])([^\[]+)(\[\/\2\])/i, next = true, step = 1; while( next ) { next = false; text = text.replace( re, function( all, tagattr, tag, attr, content, close ) { next = true; alert( [tagattr, tag, attr, content, close] ); return '<' + tag + '>' + content + '</' + tag + '>'; }); if ( !next && step++ == 1 ) { next = true; re = /(\[\s*([a-z]+)\s*(?:=?\s*([^\]]+))?\])(.*?)(\[\/\2\])/i; } } alert( text ); |
var text = 'test [b]blah\n\ [i]tata[/i] blah[/b] param [quote="test"]d[quote="test2"]lalsd[li]fnsdf[alalsdfsda[/quote] qweqweqwe [u]ter[u]t[/quote]et[/u]er[/u] hjf [u]sdhg[/u] end'; var chang = '¬'; //Строка замены для "[" var re = /(\[([a-z]+)(?:="?([^\]]+?))?"?\])([^\[]*)(\[\/\2\])/gi, next = true, step = 1; while( next ) { next = false; if(step==1)text = text.replace( re, function( all, tagattr, tag, attr, content, close ) { next = true; //alert( [step,tagattr, tag, attr, content, close] ); return '<' + tag + '>' + content + '</' + tag + '>'; }); if ( !next) {step = 2; text = text.replace(/^([\s\S]*?)(\[\/([a-z]+)\])([\s\S]*)$/i, function(str,strST,tagEnd, tag, strEnd) { next = true; var end = strST.length, st = strST.lastIndexOf('['+tag); if(st<0) return strST + chang+'/'+ tag + ']' + strEnd; var find = text.substring(st,end), rega = '^\\['+tag+'(?:="?([^\\[\\]]+?))?"?\\]([\\s\\S]*)$'; var found = find.replace(RegExp(rega,'i'), function(str,attr,content) {return '<'+tag+'>'+ content.replace(/\[/g, chang) + '</'+tag+'>'}); return text.substr(0,st) + (found!=find ? found : chang + find.slice(1)+ tagEnd) + strEnd; }) } } text = text.replace(RegExp(chang,'g'),'['); //возвращаем скобку; alert( text ); Чуть ускорил, сделав первый проход глобальным поиском (/gi), На Втором проверка неполных вложенных тегов (Исключаем ситуации типа [div][li][/div][/li]; подменяем у них символ \[) =================== В принципе вторая часть работает и самостоятельно, но совместно с первой, получаем приличное ускорение на тегах без квадратных скобок внутри |
Deff, ты его четыре года писал? :D
|
Понимаю что тема старая :)
но раз уж всплыла, то вот мой вариант. Здесь в упрощенном виде, только самые простые теги, чтобы нагляднее была идея. А идея вот в чем: когда натыкаемся на открывающий тег, кладем его в стек. Если встретили закрывающий, то проверяем его соответствие верхушке стека, если не соответствует, оставляем бб-код, иначе ставим закрывающий и убираем со стека. В конце, если что-то осталось на стеке, добиваем "закрывашками". var parseBB = function(str) { if (!str) { return str; } var rx = /\[(\/?)(b|i|u|s)\s*\]/gi; var stack = []; str = str.replace(rx, function(m, close, tag) { tag = tag.toLowerCase(); if (close) { if (!stack.length || (stack[stack.length - 1] !== tag)) { return m; } stack.pop(); } else { stack.push(tag); } return "<" + close + tag + ">"; }); if (stack.length) { str = str + stack.reverse().map(function(tag) { return "</" + tag + ">"; }).join(""); } return str; }; |
trikadin,
Нет, у мну 4 дня назад встала тема быстрого предпросмотра сообщений в топике(точнее мгновенного, по мере ввода), поискал в инете, наткнулся на эту тему, остальные Варианты были хуже |
Цитата:
2. Задача по топику была делать не рекурсией(кушает много памяти при длинных строках с много тегами), а простым повтором через while 3. Нун вначале искать первый тег закрытия от начала строки и двигаться вверх до его "открывашки", только тогда не будет пересекающихся тегов(или конфликтов), если вдобавок на всём пути, пройденного до найденной "открывашки", убиваем(подменяем, с возвратом в конце распарса) все открывающиеся скобки "[" , ибо внутри не может быть валидных вложенных ВВ-тегов по определению. Если "открывашка" не найдена, убиваем открывающуюся скобку "[" у найденного первоначального тега-"закрывашки" . Крутим цикл пока не будут найдены все('ближайшие от начала') "закрывашки" ... |
Яростный Меч,
Тест: (тег [quote="test2"] - валидный - пропущен, по идее валидный и первый, но тут можно оспорить, ты сделал валидными теги [u] var parseBB = function(str) { if (!str) { return str; } var rx = /\[(\/?)(b|i|u|s)\s*\]/gi; var stack = []; str = str.replace(rx, function(m, close, tag) { tag = tag.toLowerCase(); if (close) { if (!stack.length || (stack[stack.length - 1] !== tag)) { return m; } stack.pop(); } else { stack.push(tag); } return "<" + close + tag + ">"; }); if (stack.length) { str = str + stack.reverse().map(function(tag) { return "</" + tag + ">"; }).join(""); } return str; }; var text = 'test [b]blah\n\ [i]tata[/i] blah[/b] param [quote="test"]d[quote="test2"]lalsd[li]fnsdf[alalsdfsda[/quote] qweqweqwe [u]ter[u]t[/quote]et[/u]er[/u] hjf [u]sdhg[/u] end'; alert(parseBB(text)); //Убрал атрибуты, сменил quote на s //Да, тут терпимо, но: у [/s] - концовка осталась (ошибки в закрывашках критичны - цитата - тег <div> убила бы страницу) var text2 = 'test [b]blah\n\ [i]tata[/i] blah[/b] param [s]d[s]lalsd[li]fnsdf[alalsdfsda[/s] qweqweqwe [u]ter[u]t[/s]et[/u]er[/u] hjf [u]sdhg[/u] end'; alert(parseBB(text2)) Вдобавок у меня, при парсе на лету, когда юзер не закончил строку, желателен максимальный распарс тегов //Тут ксать у мну и таблицы еще есть, пока не додумал как парсить исключения-ошибки отсутствия некоторых тегов) |
Цитата:
Цитата:
---- На форумах бывает тег оформления исходного кода, в котором теги [b] и т.п. вообще не заменяются. Твой способ сумеет такое поддержать? Мой - запросто, если при нахождении такого тега включать специальный режим "незамены". |
Яростный Меч,
Ну идея была такая: вкладывать в тег перепарсенной "открывашки" атрибут data-исходник в котором прописывать исходный код полного bb-teга в еncode, ибо парсятся все (а у меня есть и таблицы) если какой то тег в табле отсутствует, то нун возвращать теги в BB-код, что при JQ делается парой строк На самом деле будут возвращаться все(до распарса в HTML), не прописанные в объекте перепарса (это на этапе самого распарса, не стал усложнять код незначимыми подробностями) Ибо у меня много кодов трансформируемых в несколько тегов и вставкой атрибутов Вот эта функция будет браться из объекта с описанными функциями распарса по тегам var found = find.replace(RegExp(rega,'i'), function(str,attr,content) {return '<'+tag+'>'+ content.replace(/\[/g, chang) + '</'+tag+'>'}); |
Часовой пояс GMT +3, время: 00:50. |