2010-03-10 82 views
1

我編寫了一個類似於我用來編寫此消息的Javascript bbcode。它還包含一個像我在下面看到的預覽框。我目前面臨的唯一問題是一些嵌套的bbcode不能解析。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</code></pre>', 
        '[list$1]$2<li>$3</li>$4', 
        '<ul>$1</ul>', 
        '<ol start=$1>$2</ol>', 
        '%lb%%lb%' 

        ]; 

    // fix [*] so that they only work inside [/list] 
    for(var i in find) 
    { 
     txt = txt.replace(find[i],replace[i]); 
     if(i == 17) while(txt.match(find[i],replace[i])) txt = txt.replace(find[i],replace[i]); 
    } 

    // Fix Smilies 
    txt = txt.replace(/%lb%/g,'<br />'); 
    txt = txt.replace(/\:\)/g, '<img class="smiley" src="/img/smilies/smile.gif">'); 
    txt = txt.replace(/\:-\)/g, '<img class="smiley" src="/img/smilies/happy.gif">'); 
    txt = txt.replace(/\:D/g, '<img class="smiley" src="/img/smilies/biggrin.gif">'); 
    txt = txt.replace(/\:\(/g, '<img class="smiley" src="/img/smilies/sad.gif">'); 
    txt = txt.replace(/8\)/g, '<img class="smiley" src="/img/smilies/cool.gif">'); 
    txt = txt.replace(/=O/g, '<img class="smiley" src="/img/smilies/surprised.gif">'); 
    txt = txt.replace(/\:-\|\|/g, '<img class="smiley" src="/img/smilies/mad.gif">'); 
    txt = txt.replace(/\:P/g, '<img class="smiley" src="/img/smilies/stongue.gif">'); 
    txt = txt.replace(/\}\-\(/g, '<img class="smiley" src="/img/smilies/confused.gif">'); 

    // Format Dates 
    txt = txt.replace(/\d{10}/g, function($0) { 
     var d = new Date($0*1000); 
     var months = new Array('January','February','March','April','May','June','July','August','September','October','November','December'); 
     return "" + months[d.getMonth()] + " " + d.getDate() + ", " + d.getFullYear() + ", " + (d.getHours()%12) + ":" + d.getMinutes() + " " + (d.getHours()<12 ? 'AM' : 'PM'); 
    }); 

    // Update the preview box 
    $('.preview').html(txt); 
} 

這翻轉了大多數我所有的bbcode標籤。 quote標籤有問題,因爲它有時不會翻轉嵌套的引號標籤或解析內部引號標籤的內容。

如果有人能夠提供解決方案,我將非常感激。謝謝!

+4

您的BBCode不是常規語言,因此無法用正則表達式進行分析。編寫一個解析器,跟蹤打開和關閉的標籤以找到匹配的對。因此,你甚至可以發現語法錯誤(錯誤的嵌套,缺少打開/關閉標籤等)。 – Gumbo 2010-03-10 23:01:32

+0

同樣適用於HTML:http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – 2010-03-10 23:26:30

回答

5

三種解決方案:

  1. 寫解析器。這將產生最好的解決方案,但需要花費不少的努力。

  2. 查找BBCode解析庫。質量可能和#1一樣好,而且相當容易。

  3. 向每個標記正則表達式的內部添加一個負向前視並連續應用直到不匹配。例如:

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

    這將捕獲內部報價,然後一旦它被替換,外部報價。幾乎沒有其他兩個乾淨,但可能是最快的修復。

+1

我強烈建議#2:現有的圖書館可能會比你自己少一些,至少在第一位。 – 2010-03-10 23:46:27