Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #41 (permalink)  
Старый 22.01.2012, 19:31
Аватар для trikadin
Модератор
Отправить личное сообщение для trikadin Посмотреть профиль Найти все сообщения от trikadin
 
Регистрация: 27.04.2010
Сообщений: 3,417

Сообщение от Gozar
на скорости правда это не отразилось, может мало циклов,
Да и не должно было - тут же происходит каждый раз два переприсвоения в цикле) А в твоём варианте - только одно)
__________________
Читайте:
Ты любопытный) Всё-таки, ничему в этом мире не помешает хорошая доля юмора)
Как спросить, чтобы вам ответили
Часто Задаваемые Вопросы (FAQ)
Ответить с цитированием
  #42 (permalink)  
Старый 23.01.2012, 13:34
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

да, что-то более лучшего ничего не выходит, только так:

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 );
Ответить с цитированием
  #43 (permalink)  
Старый 05.01.2016, 01:37
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

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, 09.01.2016 в 07:25.
Ответить с цитированием
  #44 (permalink)  
Старый 05.01.2016, 21:11
Аватар для trikadin
Модератор
Отправить личное сообщение для trikadin Посмотреть профиль Найти все сообщения от trikadin
 
Регистрация: 27.04.2010
Сообщений: 3,417

Deff, ты его четыре года писал?
__________________
Читайте:
Ты любопытный) Всё-таки, ничему в этом мире не помешает хорошая доля юмора)
Как спросить, чтобы вам ответили
Часто Задаваемые Вопросы (FAQ)
Ответить с цитированием
  #45 (permalink)  
Старый 05.01.2016, 21:29
Профессор
Отправить личное сообщение для Яростный Меч Посмотреть профиль Найти все сообщения от Яростный Меч
 
Регистрация: 12.04.2010
Сообщений: 557

Понимаю что тема старая
но раз уж всплыла, то вот мой вариант. Здесь в упрощенном виде, только самые простые теги, чтобы нагляднее была идея. А идея вот в чем: когда натыкаемся на открывающий тег, кладем его в стек. Если встретили закрывающий, то проверяем его соответствие верхушке стека, если не соответствует, оставляем бб-код, иначе ставим закрывающий и убираем со стека. В конце, если что-то осталось на стеке, добиваем "закрывашками".

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;
};
Ответить с цитированием
  #46 (permalink)  
Старый 07.01.2016, 01:43
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

trikadin,
Нет, у мну 4 дня назад встала тема быстрого предпросмотра сообщений в топике(точнее мгновенного, по мере ввода), поискал в инете, наткнулся на эту тему, остальные Варианты были хуже

Последний раз редактировалось Deff, 07.01.2016 в 02:35.
Ответить с цитированием
  #47 (permalink)  
Старый 07.01.2016, 01:46
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

Сообщение от Яростный Меч
иначе ставим закрывающий и убираем со стека. В конце, если что-то осталось на стеке, добиваем "закрывашками".
У мну лучше, 1. Решена проблема пересекающихся(или неполных) тегов
2. Задача по топику была делать не рекурсией(кушает много памяти при длинных строках с много тегами), а простым повтором через while
3. Нун вначале искать первый тег закрытия от начала строки и двигаться вверх до его "открывашки", только тогда не будет пересекающихся тегов(или конфликтов), если вдобавок на всём пути, пройденного до найденной "открывашки", убиваем(подменяем, с возвратом в конце распарса) все открывающиеся скобки "[" , ибо внутри не может быть валидных вложенных ВВ-тегов по определению.
Если "открывашка" не найдена, убиваем открывающуюся скобку "[" у найденного первоначального тега-"закрывашки" .
Крутим цикл пока не будут найдены все('ближайшие от начала') "закрывашки" ...

Последний раз редактировалось Deff, 07.01.2016 в 02:44.
Ответить с цитированием
  #48 (permalink)  
Старый 07.01.2016, 03:01
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

Яростный Меч,
Тест: (тег [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))

Вдобавок у меня, при парсе на лету, когда юзер не закончил строку, желателен максимальный распарс тегов
//Тут ксать у мну и таблицы еще есть, пока не додумал как парсить исключения-ошибки отсутствия некоторых тегов)

Последний раз редактировалось Deff, 07.01.2016 в 04:23.
Ответить с цитированием
  #49 (permalink)  
Старый 07.01.2016, 03:23
Профессор
Отправить личное сообщение для Яростный Меч Посмотреть профиль Найти все сообщения от Яростный Меч
 
Регистрация: 12.04.2010
Сообщений: 557

Сообщение от Deff Посмотреть сообщение
1. Решена проблема пересекающихся(или неполных) тегов
У меня тоже решена, правда, на скорую руку примитивным способом, но тут можно допилить работу со стеком, и сделать по нормальному, не меняя общий подход. Не получится только игнорировать открывающий тег, для которого нет закрывашки, т.к. нет заглядывания вперед.

Сообщение от Deff Посмотреть сообщение
2. Задача по топику была делать не рекурсией(кушает много памяти при длинных строках с много тегами), а простым повтором через while
В моём случае всё делается за один replace. Т.е. по затратам памяти имеем только исходную строку и результат.


----
На форумах бывает тег оформления исходного кода, в котором теги [b] и т.п. вообще не заменяются. Твой способ сумеет такое поддержать? Мой - запросто, если при нахождении такого тега включать специальный режим "незамены".
Ответить с цитированием
  #50 (permalink)  
Старый 07.01.2016, 03:41
без статуса
Отправить личное сообщение для Deff Посмотреть профиль Найти все сообщения от Deff
 
Регистрация: 25.05.2012
Сообщений: 8,219

Яростный Меч,
Ну идея была такая: вкладывать в тег перепарсенной "открывашки" атрибут 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+'>'});

Последний раз редактировалось Deff, 07.01.2016 в 04:01.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Парсинг даты Allan Stark Общие вопросы Javascript 4 30.01.2014 18:57
Парсинг времени Falcon Общие вопросы Javascript 2 20.09.2010 17:23
custom Парсинг HTML нужен Increazon Общие вопросы Javascript 8 15.09.2010 13:23
Ищу скрипт для работы с bbcode mTzen Общие вопросы Javascript 3 13.09.2010 07:17
bbcode, iframe и javascript Dark[Ol(U23)leneri] Я не знаю javascript 0 10.06.2009 19:52