Модераторы: Sardar, Aliance

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите подправить кодировщик 
:(
    Опции темы
animegirl
Дата 13.7.2013, 20:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Незнайка на Марсе
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 24.7.2011

Репутация: нет
Всего: нет



В своей работе, использую функцию по перекодированию ббкод тэгов в обычные ХТМЛ тэги, проблема в том, что некоторые вложенные тэги создают ошибки.
Моя функция:
Код

function code_to_html(text)
    {
    search = new Array(
        /\[b\](.*?)\[\/b\]/ig,
        /\[i\](.*?)\[\/i\]/ig,
        /\[u\](.*?)\[\/u\]/ig,
        /\[s\](.*?)\[\/s\]/ig,
        /\[url\](.*?)\[\/url\]/ig,
        /\[url\="?(.*?)"?\](.*?)\[\/url\]/ig,
        /\[img\](.*?)\[\/img\]/ig,
        /\[quote](.*?)\[\/quote\]/igm,
        /\[quote\="?(.*?)"?\](.*?)\[\/quote\]/igm);

    replace = new Array(
        "<span class=\"code_b\">$1</span>",
        "<span class=\"code_i\">$1</span>",
        "<span class=\"code_u\">$1</span>",
        "<span class=\"code_s\">$1</span>",
        "<a href=\"$1\" rel=\"nofollow\">$1</a>",
        "<a href=\"$1\" rel=\"nofollow\">$2</a>",
        "<img src=\"$1\" alt=\"An image\">",
        "<div class=\"quote_div\">$1</div>",
        "<div class=\"quote_div\"><div class=\"quote_author_div\">$1 wrote:</div>$2</div>");

    for(i = 0; i < search.length; i++)
        {
        text = text.replace(search[i],replace[i]);
        }

    return text;
    }


Если сделать вложенное цитирование, например так
Код

[quote]a[quote]b[/quote][/quote]c

то я в итоге получаю блок цитаты с 
Код

a[quote]b

 внутри и 
Код
[/quote]c

снаружи.

Как мне подправить мою функцию, чтобы она могла разбирать вложенные тэги, без таких коллизий?

 smile 


--------------------
Скажи миру - НЯ!
PM   Вверх
Arantir
Дата 13.7.2013, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Рыбак без удочки
**


Профиль
Группа: Участник
Сообщений: 960
Регистрация: 18.11.2012

Репутация: 14
Всего: 55



Для начала - не использовать ленивые выражения для допускающих вложенность тегов.
Точка - любой символ. Так что 
Код

/\[quote\](.*)\[\/quote\]/igm
захавает самый первый [ quote ] и самый последний [ /quote ].

После этого получится
Код

<div class=\"quote_div\">a[quote]b[/quote]</div>c
так что придется найденное группой (.*) пропарсить еще раз.

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

Это сообщение отредактировал(а) Arantir - 13.7.2013, 20:52


--------------------
interface Жопа {
    // ATTENTION: has to be implemented by every class of the project for proper project work
}
PM   Вверх
animegirl
Дата 13.7.2013, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Незнайка на Марсе
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 24.7.2011

Репутация: нет
Всего: нет



Arantir
Колдую над регуляркой, хочу её подправить, там где вы правильно указали, вместо "любой символ", хочу сделать "любой символ, кроме [цитата]", чё-то как не кручу, результат нулевой, хотя бы внутренняя цитаты обработалась бы, уже было чуток проще (

Добавлено через 29 секунд
Код

/\[quote\](^[\[quote\]][.*?])\[\/quote\]/igm,



--------------------
Скажи миру - НЯ!
PM   Вверх
Arantir
Дата 13.7.2013, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Рыбак без удочки
**


Профиль
Группа: Участник
Сообщений: 960
Регистрация: 18.11.2012

Репутация: 14
Всего: 55



А почему бы просто не заменить все [quоte] на <div class="quote_div">, а все [/quоte] на </div>?  smile 

Цитата(animegirl @  13.7.2013,  20:43 Найти цитируемый пост)
вместо "любой символ", хочу сделать "любой символ, кроме [цитата]"

Это ломает всю идею. Регулярке на другие [quоte] и так наплевать. В ней же они только по одному разу указаны, один раз она их и найдет - самую ближнюю и самую дальнюю, а между ними - все, что угодно.
Суть идеи была в том, чтобы вот это все между ними пропустить через замену еще раз. И так пока там не останется в ни одной [quоte] в очередном вхождении.


--------------------
interface Жопа {
    // ATTENTION: has to be implemented by every class of the project for proper project work
}
PM   Вверх
animegirl
Дата 13.7.2013, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Незнайка на Марсе
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 24.7.2011

Репутация: нет
Всего: нет



Arantir
Долго пыталась понять "А реально, почему бы и нет?", а потом поняла, да очень просто, если юзер не закроет тэг, он сможет сломать весь вид. А это раздолье для вандалов.

Добавлено через 1 минуту и 15 секунд
Arantir
По поводу ломки идеи, как раз таки нет, я поставлю процесс на рекурсию, и выходом будет тот факт, что строка не изменила свой вид.


--------------------
Скажи миру - НЯ!
PM   Вверх
Arantir
Дата 13.7.2013, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Рыбак без удочки
**


Профиль
Группа: Участник
Сообщений: 960
Регистрация: 18.11.2012

Репутация: 14
Всего: 55



Цитата(animegirl @  13.7.2013,  21:26 Найти цитируемый пост)
я поставлю процесс на рекурсию, и выходом будет тот факт, что строка не изменила свой вид. 

Для этого не обязательно 
Цитата(animegirl @  13.7.2013,  20:43 Найти цитируемый пост)
вместо "любой символ", хочу сделать "любой символ, кроме [цитата]"


Например, для строки 
Код

0[quote]1[quote]2[quote]3[/quote][/quote]4[/quote]5[/quote]6
рекурсия приведет к 
Код

3[/quote]
в чем нету
Код

/\[quote\](.*)\[\/quote\]/igm
 а так как не нашлось указанной группы, то рекурсия остановится (нет для кого ее продолжить).

Это сообщение отредактировал(а) Arantir - 13.7.2013, 22:45


--------------------
interface Жопа {
    // ATTENTION: has to be implemented by every class of the project for proper project work
}
PM   Вверх
animegirl
Дата 13.7.2013, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Незнайка на Марсе
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 24.7.2011

Репутация: нет
Всего: нет



Arantir
Не поняла, почему? Вот как я вижу эту рекурсию:

Код

function code_to_html(text)
    {
    var old_text = null;
    do
        {
        old_text = text;
        search = new Array(
            /\[quote\](^[\[quote\]])\[\/quote\]/igm,
            /\[quote\="?(.*?)"?\](.*?)\[\/quote\]/igm,
            );
        
        replace = new Array(
            "<div class=\"quote_div\">$1</div>",
            "<div class=\"quote_div\"><div class=\"quote_author_div\">$1 wrote:</div>$2</div>",
            );
        
        for(i = 0; i < search.length; i++)
            {
            text = text.replace(search[i],replace[i]);
            }
        }
    while(text !== old_text);
    
    return text;
    }


Это сообщение отредактировал(а) animegirl - 13.7.2013, 23:02


--------------------
Скажи миру - НЯ!
PM   Вверх
Arantir
Дата 13.7.2013, 23:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Рыбак без удочки
**


Профиль
Группа: Участник
Сообщений: 960
Регистрация: 18.11.2012

Репутация: 14
Всего: 55



В физическом представлении моя доселе неосязаемая идея выглядит так:
Код

    function includable_tags(pattern, replace, text)
    {
        var match = (new RegExp(pattern[0], pattern[1])).exec(text);
        if (match == null)
            return text;
        if ((new RegExp(pattern[0], pattern[1])).exec(match[1]) == null)
            return text.replace((new RegExp(pattern[0], pattern[1])), replace);
        return includable_tags(pattern, replace, text.replace(match[1], includable_tags(pattern, replace, match[1])));
    }
Из-за того, что объекты передаются по ссылкам пришлось каждый раз создавать новый regexp, чтобы рекурсия не сломалась, так как результаты поиска в нем оставались бы старые.

Тест:
Код

    var p = ['\\[quote\\](.*)\\[/quote\\]', 'gim'];
    var r = "<div class=\"quote_div\">$1</div>";
    console.log(includable_tags(p,r,"3"));
    console.log(includable_tags(p,r,"2[quote]3[/quote]4"));
    console.log(includable_tags(p,r,"1[quote]2[quote]3[/quote]4[/quote]5"));
    console.log(includable_tags(p,r,"0[quote]1[quote]2[quote]3[/quote]4[/quote]5[/quote]6"));
    console.log(includable_tags(p,r,"0[quote]1[quote]2[quote]3[/quote][/quote]4[/quote]5[/quote]6"));
    console.log(includable_tags(p,r,"[quote]0[quote]1[quote]2[quote]3[/quote]4[/quote]5[/quote]6"));



Это сообщение отредактировал(а) Arantir - 13.7.2013, 23:02


--------------------
interface Жопа {
    // ATTENTION: has to be implemented by every class of the project for proper project work
}
PM   Вверх
animegirl
Дата 13.7.2013, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Незнайка на Марсе
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 24.7.2011

Репутация: нет
Всего: нет



В вашем примере выводятся 2 ошибки, которые неприемлемы логике вложеных тэгов, а именно в примерах

Код

console.log(includable_tags(p,r,"0[quote]1[quote]2[quote]3[/quote][/quote]4[/quote]5[/quote]6"));
console.log(includable_tags(p,r,"[quote]0[quote]1[quote]2[quote]3[/quote]4[/quote]5[/quote]6"));


там выдаётся 

Код

0<div class="quote_div">1<div class="quote_div">2<div class="quote_div">3[/quote]</div>4</div>5</div>6
<div class="quote_div">0<div class="quote_div">1<div class="quote_div">2[quote]3</div>4</div>5</div>6


хотя должно выглядеть так:
Код

0<div>1<div>2<div>3</div></div>4</div>5[/quote]6
[quote]0<div>1<div>2<div>3</div>4</div>5</div>6


Добавлено через 1 минуту и 25 секунд
Так в итоге, как переделать строку
/\[quote](.*?)\[\/quote\]/igm,
что бы там по середине исключалось открывание тэга [цитата]?


--------------------
Скажи миру - НЯ!
PM   Вверх
Arantir
Дата 13.7.2013, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Рыбак без удочки
**


Профиль
Группа: Участник
Сообщений: 960
Регистрация: 18.11.2012

Репутация: 14
Всего: 55



Цитата(animegirl @  13.7.2013,  21:59 Найти цитируемый пост)
while(text !== old_text);

Это бы прокатило и с обычным вариантом:
Код

/\[quote\](.*)\[\/quote\]/igm

Просто с ним бы заменяло снаружи внутрь, а у Вас изнутри наружу. Мой вариант ищет крайние внешние, а Ваш - самые внутренние (которые без вложений).
В обоих случаях постоянная замена в конце концов все позаменяет.

Мой вариант с рекурсией лишь не ищет в лишнем тексте и не сравнивает его весь целиком. 


Цитата(animegirl @  13.7.2013,  21:59 Найти цитируемый пост)
/\[quоte\](^[\[quоte\]])\[\/quоte\]/igm

Код

/\[quote\]([^\[quote\]])*\[\/quote\]/igm
без опечаток smile

Добавлено через 9 минут и 7 секунд
Цитата(animegirl @  13.7.2013,  22:10 Найти цитируемый пост)
В вашем примере выводятся 2 ошибки, которые неприемлемы логике вложеных тэгов

Ну, вообще-то, после парсинга это уже не теги, а просто буковки в HTML-коде.

Цитата(animegirl @  13.7.2013,  22:10 Найти цитируемый пост)
хотя должно выглядеть так

В любом случае скрипт не может наверняка узнать, в каком именно месте пропущен тег. 
А что, если я пропустил его перед тройкой, а не перед ноликов, и так как у Вас быть не должно? =)

Да и вообще:
Код

code_to_html(text);
var match = (new RegExp('\\[/?quote\\]', 'gim')).exec(text);
if (match != null)
    alert("У вас наден потеряный тег quote. Проверьте разметку");


Это сообщение отредактировал(а) Arantir - 13.7.2013, 23:16


--------------------
interface Жопа {
    // ATTENTION: has to be implemented by every class of the project for proper project work
}
PM   Вверх
animegirl
Дата 13.7.2013, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Незнайка на Марсе
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 24.7.2011

Репутация: нет
Всего: нет



Arantir
Код

/\[quote\]([^\[quote\]])*\[\/quote\]/igm

приводит к той ошибке, что внутрений тэг меняется, а последующие внешние - нет.
там надо сделать "не тэг цитаты И чтоб хотя бы один знак любой"

Добавлено через 13 минут и 25 секунд
Arantir
Готово, спасибо за пинание извилин в правильном направление ;)

f
Код

unction code_to_html(text)
    {
    var old_text = null;
    do
        {
        old_text = text;
        search = new Array(
            /\[quote\]([^\[quote\]])(.*?)\[\/quote\]/igm
            );
        
        replace = new Array(
           "<div class=\"quote_div\">$1$2</div>"
            );
        
        for(i = 0; i < search.length; i++)
            {
            text = text.replace(search[i],replace[i]);
            }
        }
    while(text !== old_text);
    
    return text;
    }


Логика регулярок для меня всё равно остаётся на уровне бизона хигинса, но задача выполняется как надо )


--------------------
Скажи миру - НЯ!
PM   Вверх
animegirl
Дата 14.7.2013, 03:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Незнайка на Марсе
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 24.7.2011

Репутация: нет
Всего: нет



Пытаюс добавить туда отказ обработки пустых цитат, на ум пришло сделать так:
Код

/\[quote\]([^\[quote\]]|^[.*]^[^<div.*>.*<\/div>]*?$|.*?)\[\/quote\]/igm

но на деле не работает (


--------------------
Скажи миру - НЯ!
PM   Вверх
ksnk
Дата 14.7.2013, 08:58 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 84
Всего: 386



animegirl, Парсинг bb - не самая простая задача. Для сложных вложенных тегов с параметрами, вообще говоря - комплектом регулярок не решается. Обычно, такое делается, используя "автомат со стеком". Выедается открывающий тег, укладывается на стек, когда встречается закрывающий тег - со стека берется последний открытый и с этой парой уже идет трансформация...
На phpclub (внезапно?  smile ) возникла тема про Bb коды. Там проскакивала ссылка на простой парсер bb на JS. Действительно простой. Возможно, даже излишне, сложных параметров не понимает, но это несложно исправить. В качестве варианта парсера вполне пригоден.

Другое дело, нужен ли парсер на JS или его уместнее делать на сервере?



--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Arantir
Дата 14.7.2013, 08:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Рыбак без удочки
**


Профиль
Группа: Участник
Сообщений: 960
Регистрация: 18.11.2012

Репутация: 14
Всего: 55



Иногда проще разбить сложную задачу на подзадачи. У пользователей компы не бесконечно мощные, пожалейте их немножко smile

Можно перед обработкой просто удалять все пустые \[quote\].
Заменять 
Код

/\[quote\]\s*\[\/quote\]/igm
пустой строкой

А что останется - уже парсить в HTML.

Добавлено через 8 минут и 11 секунд
Цитата(ksnk @  14.7.2013,  07:58 Найти цитируемый пост)
Выедается открывающий тег, укладывается на стек, когда встречается закрывающий тег - со стека берется последний открытый и с этой парой уже идет трансформация...

Да, кстати, во многих форумных движках так и делается.

Цитата(ksnk @  14.7.2013,  07:58 Найти цитируемый пост)
Другое дело, нужен ли парсер на JS или его уместнее делать на сервере?

Может это просто WYSIWYG. В том числе, способ разгрузить сервер.
А раз не сервер - сверхэффективный алгоритм делать не обязательно.


--------------------
interface Жопа {
    // ATTENTION: has to be implemented by every class of the project for proper project work
}
PM   Вверх
animegirl
Дата 14.7.2013, 18:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Незнайка на Марсе
**


Профиль
Группа: Участник
Сообщений: 326
Регистрация: 24.7.2011

Репутация: нет
Всего: нет



Цитата(ksnk @ 14.7.2013,  08:58)
animegirl, Парсинг bb - не самая простая задача. Для сложных вложенных тегов с параметрами, вообще говоря - комплектом регулярок не решается. Обычно, такое делается, используя "автомат со стеком". Выедается открывающий тег, укладывается на стек, когда встречается закрывающий тег - со стека берется последний открытый и с этой парой уже идет трансформация...
На phpclub (внезапно?  smile ) возникла тема про Bb коды. Там проскакивала ссылка на простой парсер bb на JS. Действительно простой. Возможно, даже излишне, сложных параметров не понимает, но это несложно исправить. В качестве варианта парсера вполне пригоден.

Другое дело, нужен ли парсер на JS или его уместнее делать на сервере?

Нужен на JS, причины:
- сервер передаёт данные один раз в том же виде, что юзер их отправлял
- то что показывается юзеру, это уже переделанное на ХТМЛ, но исходники остаются в памяти, что бы в случае цитаты, их сразу можно было вставить, иначе же прядётся ещё более сложными регулярками их парсить обратно
- Страница сайта полностью на JS и не перегружается, гонять несколько раз данные, чтоб сначала уже в ХТМЛ а для правки ещё раз в ББкоде -> траффик
- С одной стороны да - мы грузим бруазер юзеру, с другой разгружаем свои сервера лишней работой.

Добавлено через 14 минут и 44 секунды
Цитата(Arantir @  14.7.2013,  08:59 Найти цитируемый пост)
Можно перед обработкой просто удалять все пустые

В том то и проблема, что они могут быть не пустыми, я скорее о такой конструкции:
Код

1[quote][quote]3[/quote][/quote]5

То есть, после первой замены внутренней цитаты, там в строке будет див, тем самым внешняя цитата по логике регулярки пустой не будет, а мне надо, чтоб она игнорировалась, в связи с тем, что кроме самих цитат внутри, там пустота вокруг.


--------------------
Скажи миру - НЯ!
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0970 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.