Javascript не анализирует вложенный Bbcode - PullRequest
1 голос
/ 11 марта 2010

Я кодировал bb-код Javascript, аналогичный тому, который я использую для написания этого сообщения. Он также включает окно предварительного просмотра, подобное тому, которое я вижу ниже. Единственная проблема, с которой я сталкиваюсь на данный момент, заключается в том, что некоторый вложенный bbcode не анализируется.

Например:

[quote]
   [quote][/quote]
[/quote]

Неправильный анализ.

Это мой Javascript в настоящее время.

function preview() {

    var txt = $('#editor').val();
    txt = txt.replace(/</g,'&lt;');
    txt = txt.replace(/>/g,'&gt;');

    txt = txt.replace(/[\r\n]/g,'%lb%');

    var find    = [
                   /\[quote\](.*?)\[\/quote\]/gi,
                   /\[quote author="(.*?)" date="(.*?)"\](.*?)\[\/quote\]/gi,
                   /\[b\](.*?)\[\/b\]/gi,
                   /\[i\](.*?)\[\/i\]/gi,
                   /\[u\](.*?)\[\/u\]/gi,
                   /\[left\](.*?)\[\/left\]/gi,
                   /\[center\](.*?)\[\/center\]/gi,
                   /\[right\](.*?)\[\/right\]/gi,
                   /\[size=(10|12|24|30)](.*?)\[\/size\]/gi,
                   /\[font=(.*?)](.*?)\[\/font\]/gi,
                   /\[color=(.*?)](.*?)\[\/color\]/gi,
                   /\[url(?:\=?)(.*?)\](.*?)\[\/url\]/gi,
                   /\[email=(.*?)\](.*?)\[\/email\]/gi,
                   /\[email\](.*?)\[\/email\]/gi,
                   /\[img(.*?)\](.*?)\[\/img\]/gi,
                   /(?:%lb%|\s)*\[code(?:\=?)(?:.*?)\](?:%lb%|\s)*(.*?)(?:%lb%|\s)*\[\/code\](?:%lb%|\s)*/gi,

                   /\[list(.*?)\](.*?)\[\*\](.*?)(?:%lb%|\s)*(\[\*\].*?\[\/list\]|\[\/list\])/i,
                   /(?:%lb%|\s)*\[list\](?:%lb%|\s)*(.*?)(?:%lb%|\s)*\[\/list\](?:%lb%|\s)*/gi,
                   /(?:%lb%|\s)*\[list=(\d)\](?:%lb%|\s)*(.*?)(?:%lb%|\s)*\[\/list\](?:%lb%|\s)*/gi,
                   /(?:%lb%){3,}/g

                   ];
    var replace = [
                   '<blockquote><div class="quote"><div class="quote_body">$1</div></div></blockquote>',
                   '<blockquote><div class="quote"><div class="quote_author"><span class="quote_from">Quote from</span> <span class="author">$1</span> on <span class="date">$2</span></div><div class="quote_body">$3</div></div></blockquote>',
                   '<b>$1<\/b>',
                   '<i>$1<\/i>',
                   '<u>$1<\/u>',
                   '<div class="align_left">$1<\/div>',
                   '<div class="align_center">$1<\/div>',
                   '<div class="align_right">$1<\/div>',
                   '<span style="font-size:$1px;">$2</span>',
                   '<span style="font-family:$1;">$2</span>',
                   '<span style="color:$1;">$2</span>',
                   '<a href="$1">$2</a>',
                   '<a href="mailto:$1">$2</a>',
                   '<a href="mailto:$1">$1</a>',                   
                   '<img $1 src="$2" />',
                   '<pre><code>$1
», '[Список $ 1] $ * 1010 2 * $ 3 $ 4', '
', '
', '% Фунт %% фунт%' ]; // исправить [*], чтобы они работали только внутри [/ list] для (я могу найти) { txt = txt.replace (найти [i], заменить [i]); if (i == 17) while (txt.match (find [i], replace [i]))) txt = txt.replace (find [i], replace [i]); } // Исправить смайлики txt = txt.replace (/% lb% / g, '
'); txt = txt.replace (/ \: \) / g, 'image'); txt = txt.replace (/ \: - \) / g, 'image'); txt = txt.replace (/ \: D / g, 'image'); txt = txt.replace (/ \: \ (/ g, 'image'); txt = txt.replace (/ 8 \) / g, 'image'); txt = txt.replace (/ = O / g, 'image'); txt = txt.replace (/ \: - \ | \ | / g, 'image'); txt = txt.replace (/ \: P / g, 'image'); txt = txt.replace (/ \} \ - \ (/ g, 'image'); // Формат даты txt = txt.replace (/ \ d {10} / g, функция ($ 0) { var d = новая дата ($ 0 * 1000); var месяцы = новый массив («январь», «февраль», «март», «апрель», «май», «июнь», «июль», «август», «сентябрь», «октябрь», «ноябрь», 'Декабрь'); return "" + месяцы [d.getMonth ()] + "" + d.getDate () + "," + d.getFullYear () + "," + (d.getHours ()% 12) + ":" + d.getMinutes () + "" + (d.getHours ()

Это переворачивает все мои теги bbcode. Тег цитаты проблематичен тем, что иногда он не переворачивает вложенные теги цитат и не анализирует содержимое внутренних тегов цитат.

Если кто-нибудь сможет предложить решение, я был бы очень признателен. Спасибо!

1 Ответ

5 голосов
/ 11 марта 2010

Три решения:

  1. Написать парсер. Это даст наилучшее решение, но потребует нетривиальных усилий.

  2. Найти библиотеку синтаксического анализа BBCode. Вероятно, по качеству # 1 и значительно проще.

  3. Добавьте отрицательный взгляд внутрь каждого тега регулярного выражения и непрерывно применяйте до совпадения. E.g.:

    \[quote\]((?:[^](?!\[quote\]))*?)\[\/quote\]
    

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

...