2013-07-01 54 views
0

我有一個字符串,我想轉換爲div,但它並沒有正確關閉div。Javascript BBcode函數不工作

我使用的例子字符串是這樣的:

[quote]Quote by: user1 [quote]Quote by: user2 ads[/quote]Test[/quote]Testing 2. 

這導致:

<div class="quote" style="margin-left:10px;margin-top:10px;"> 
    Quote by: user1 
    [quote]Quote by: user2 ads 
</div> 
    Test[/quote]Testing 2. 

但它不會正確地轉換內部引號。

我的JavaScript函數是這樣的:

function bbcode_parser(str) { 
search = new Array(
    /\[b\](.*?)\[\/b\]/g, 
    /\[i\](.*?)\[\/i\]/g, 
    /\[quote](.*?)\[\/quote\]/g, 
    /\[\*\]\s?(.*?)\n/g); 

replace = new Array(
     "<strong>$1</strong>", 
     "<em>$1</em>", 
     "<div class='quote' style='margin-left:10px;margin-top:10px;'>$1</div>"); 

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

return str; 
} 

我提供了一個JSFiddle給你看它在行動: http://jsfiddle.net/gRaFW/2/

請幫助:)

+1

姆......用正則表達式嵌套。所以這個問題應該叫做nastying。 – acdcjunior

+0

你的正則表達式檢查正確打開和關閉''[quote]'s。它無法正確處理嵌套。老實說,你最好的選擇(使用正則表達式)只是用'

' and every '[/quote]' with '
'代替每一個'[quote]'(不檢查它們是否被正確打開或關閉,如果你擔心這個問題,你可以先計算它們。 – acdcjunior

+0

Is there沒有正則表達式更好的選擇? – Sir

回答

2

所以......你的方法很接近,但由於JavaScript的replace function工作方式,它只會替換第一個打開和第一個關閉對。由於第一次關閉後沒有打開/關閉的實例,所以替換方法在那裏停止。這裏是如何的搜索方法思考:

[quote]Quote by: user1 [quote]Quote by: user2 ads[/quote]Test[/quote]Testing 2. 
^ Found open, look for close.....................^ Found! Look for open........ 

既然在收盤後沒有打開,它停在那裏,並執行替換:

[quote]Quote by: user1 [quote]Quote by: user2 ads[/quote] 

變爲:

<div class='quote'>Quote by: user1 [quote]Quote by: user2 ads</div> 

現在整串讀取:

<div class='quote'>Quote by: user1 [quote]Quote by: user2 ads</div>Test[/quote]Testing 2. 

這一對不匹配的標籤就是你所看到的,而且它顯得有趣。但是,如果您再次執行相同的替換,則第一個替換的打開將與第二個替換的打開匹配,反之亦然。奇怪的是,但它確實確保HTML對於每個結束標記都有一個開放標記,即使輸入不是這樣,這是一個令人驚訝但卻是理想的結果。要繼續例如:

<div class='quote'>Quote by: user1 [quote]Quote by: user2 ads</div>Test[/quote]Testing 2. 
           ^Found Open, look for close........^ Found! ......... 

現在更換:

[quote]Quote by: user2 ads</div>Test[/quote] 

<div class='quote'>Quote by: user2 ads</div>Test</div> 

得到整個字符串:

<div class='quote'>Quote by: user1 <div class='quote'>Quote by: user2 ads</div>Test</div>Testing 2. 

這是你想要的到底是什麼,雖然它是一個奇怪而輕微的雖然這個方法不錯,但是HTML比其他一些可以使用的方法更安全。

我寫了一個簡單的改變你的jsfiddle簡單地重複,直到更換背到後面的替代導致相同的字符串:http://jsfiddle.net/gRaFW/6/

注意,此方法應嵌套的標籤工作,以及背返回標籤。如果標籤不匹配,這將會破壞,並且只有更復雜的邏輯,否則庫將有所幫助。這將產生2個標籤,一個開放,一個近,但不能保證這些標記相互匹配,如:

[b][quote]Broke[/b][/quote] 

所以,要小心

+0

作品魅力:D謝謝! – Sir

0

這是不可能的正確解析BBCode使用正則表達式的原因與not possible to properly parse HTML using regular expressions相同。您的BBCode分析器功能將無法工作。

+0

你有推薦的解決方案嗎? – Sir

+0

使用現有的BBCode解析器,如acdcjunior說的。 –

+0

似乎很多代碼爲這樣一個小特徵=/ – Sir

0

我幾年前做出了嘗試,但它無法在複雜的嵌套的標籤由於與想「解析」使用正則表達式的併發症:https://github.com/kaimallea/bbcode

我也扔在一起的前端,它在這裏:http://jsfiddle.net/Kai/nJdXF/ - 嘗試粘貼[quote="Someone"]Hello, there![/quote]之類的東西來測試。

您可以檢查我用引號這裏的邏輯:https://github.com/kaimallea/bbcode/blob/master/bbcode.js#L83-L94

說了這麼多,你應該嘗試尋找一個真正的解析器最好的結果。這適用於簡單的東西,但在嵌套變得瘋狂時失敗。 (例如,如果你使用PHP,這裏有一個用於PHP的BBCode擴展:http://php.net/manual/en/book.bbcode.php

+0

嗯,我可以使用PHP我希望能做到它的客戶端,所以服務器有更少的個人處理。 – Sir