2010-05-21 25 views
2

我有以下幾點:正則表達式只有在包含正則表達式匹配時纔會替換?

[list] 
[*] test 
[*] test 
[*] test 
[/list] 

,我想創建一個正則表達式,輪流到這一點:

<ul> 
<li>test</li> 
<li>test</li> 
<li>test</li> 
</ul> 

我知道足夠的正則表達式來代替簡單的標籤,但在這種情況下,我需要僅當它們包含在ul中時才替換li標籤。替換前是否有辦法檢查?

我正在使用JavaScript,如果重要。

+2

你想一個BB代碼分析器? – kennytm 2010-05-21 05:58:34

+0

這裏需要一個合適的解析器,這不是正則表達式的工作。 – gregmac 2010-05-21 06:12:31

+2

@gregmac,你不知道。如果列表沒有嵌套,並且除了那些list-thingies需要被替換爲一次動作,那麼正則表達式就沒有問題。但是,如果更廣泛的結構需要替換,或者語言可以獲得遞歸性質,那麼你是對的。但截至目前,信息太少而無法做出判斷。 – 2010-05-21 06:16:35

回答

3

中的文字:

[*] test1 

[list] 
[*] test2 
[*] test3 
[*] test4 
[/list] 

[*] test5 

的正則表達式:

\[\*]\s*([^\r\n]+)(?=((?!\[list])[\s\S])*\[/list]) 

比賽只[*] test2[*] test3[*] test4。但是,如果[list]可以嵌套,或者需要解析更廣泛的BB類語言集,我會選擇合適的解析器。

完成替換,替換我建議的正則表達式:

<li>$1</li> 

,然後替換[list]<ul>[/list]</ul>(假設[list][/list]僅用於列表和不存在的意見或字符串文字或其他)。

running the following snippet

var text = "[*] test1\n"+ 
    "\n"+ 
    "[list]\n"+ 
    "[*] test2\n"+ 
    "[*] test3\n"+ 
    "[*] test4\n"+ 
    "[/list]\n"+ 
    "\n"+ 
    "[*] test5\n"+ 
    "\n"+ 
    "[list]\n"+ 
    "[*] test6\n"+ 
    "[*] test7\n"+ 
    "[/list]\n"+ 
    "\n"+ 
    "[*] test8"; 

print(text + "\n============================"); 
text = text.replace(/\[\*]\s*([^\r\n]+)(?=((?!\[list])[\s\S])*\[\/list])/g, "<li>$1</li>"); 
text = text.replace(/\[list]/g, "<ul>"); 
text = text.replace(/\[\/list]/g, "</ul>"); 
print(text); 

印刷有以下內容:

[*] test1 

[list] 
[*] test2 
[*] test3 
[*] test4 
[/list] 

[*] test5 

[list] 
[*] test6 
[*] test7 
[/list] 

[*] test8 
============================ 
[*] test1 

<ul> 
<li>test2</li> 
<li>test3</li> 
<li>test4</li> 
</ul> 

[*] test5 

<ul> 
<li>test6</li> 
<li>test7</li> 
</ul> 

[*] test8 

一個小的解釋可能是爲了:

  • \[\*]\s*子串[*]後跟零或匹配更多的空白字符;
  • ([^\r\n]+)吞下線的其餘部分並將其保存在匹配組1中;
  • (?=((?!\[list])[\s\S])*\[/list])確保每場比賽1組必須有一個子串[/list]提前沒有 encoutering一個[list]

編輯

或者更好的,做的濃湯在這個註釋提示回答:全部匹配[list] ... [/list],然後全部替換爲[*] ...

+1

你應該做一個更系統的方法:搜索每個'[list] ... [/ list]'並且每一個匹配都替換它中每一個出現的'[*]'。 – Gumbo 2010-05-21 06:41:09

+0

@Gumbo,同意,編輯我的答案。 – 2010-05-21 06:46:10

2

這是一個更好的方法來巴特K.的建議:

  • 找到所有[list] … [/list]
  • 每場比賽,發現所有[*]在它

這將確保只有在[list] … [/list][*]將被替換。

代碼:

str.replace(/\[list]([\s\S]*?)\[\/list]/g, function($0, $1) { 
    return "<ul>" + $1.replace(/^ *\[\*] *(.*)/gm, "<li>$1</li>") + "</ul>"; 
})