2011-06-15 83 views
3

我有缺陷的投入,看起來像這樣來了...正則表達式匹配的內容,直到多字符串

foo<p>bar</p> 

而且我想它正常化包裹在AP標記領先的文字:

<p>foo</p><p>bar</p> 

這與正則表達式與<p>$1</p>/^([^<]+)/更換很容易。問題是,有時導致塊包含除P標籤,就像這樣:

foo <b>bold</b><p>bar</p> 

這應該換一個新的P整個大塊:

<p>foo <b>bold</b></p><p>bar</p> 

但由於簡單的regex只查找< ,它停在<b>和吐出:

<p>foo </p><b>bold</b><p>bar</p> <!-- oops --> 

那麼,如何重寫正則表達式匹配<p?顯然,答案涉及負面看法,但this對我來說有點太深。

(與之前的必然「你不能用正則表達式解析HTML!」的評論,輸入是不是隨機的HTML,但只有標籤<p><a><b><i>,以及A/B註釋純文本/我可能不會嵌套。)

+2

+1只是爲了最後一句。 – 2011-06-15 03:16:30

回答

3

我想你其實想積極前瞻。這真是不壞:

/^([^<]+)(?=<p)/ 

你只是想確保無論發生什麼事之後<p,但你不希望實際消耗<p,讓你用的預計。

例子:

> var re = /^([^<]+)(?=<p)/g; 

> 'foo<p>bar</p>'.replace(re, '<p>$1</p>'); 
    "<p>foo</p><p>bar</p>" 

> 'foo <b>bold</b><p>bar</p>'.replace(re, '<p>$1</p>') 
    "foo <b>bold</b><p>bar</p>" 

對不起,是不是在我原來的帖子很清楚:我的期望是,「富大膽」也一點會得到包裹在一個新的p標籤,這並沒有發生。

此外,每次不時地輸入沒有p標籤(只是普通的foo),而且還應該映射到<p>foo</p>

我發現得到這個工作最簡單的方法是使用2個獨立的正則表達式,/^(.+?(?=<p))//^([^<]+)/

> var re1 = /^(.+?(?=<p))/g, 
     re2 = /^([^<]+)/g, 
     s = '<p>$1</p>'; 

> 'foo<p>bar</p>'.replace(re1, s).replace(re2, s); 
    "<p>foo</p><p>bar</p>" 

> 'foo'.replace(re1, s).replace(re2, s); 
    "<p>foo</p>" 

> 'foo <b>bold</b><p>bar</p>'.replace(re1, s).replace(re2, s); 
    "<p>foo <b>bold</b></p><p>bar</p>" 

有可能通過合併re1re2寫單,相當於正則表達式:
/^(.+?(?=<p)|[^<]+)/

> var re3 = /^(.+?(?=<p)|[^<]+)/g, 
     s = '<p>$1</p>'; 

> 'foo<p>bar</p>'.replace(re3, s) 
    "<p>foo</p><p>bar</p>" 

> 'foo'.replace(re3, s) 
    "<p>foo</p>" 

> 'foo <b>bold</b><p>bar</p>'.replace(re3, s) 
    "<p>foo <b>bold</b></p><p>bar</p>" 
+0

對不起,在我原來的發帖中還不夠清楚:我的期望是「foo bold」位也會被換成新的p標籤,而這種情況並沒有發生。 – jpatokal 2011-06-15 03:36:51

+0

此外,每次不時有輸入,根本沒有p標籤(只是簡單的'foo'),而且還應該映射到'

foo

'。 – jpatokal 2011-06-15 03:47:11

+0

基本思想很簡單,就是文本應該總是包裹在段落中。兩個正則表達式風格很好,謝謝! – jpatokal 2011-06-15 04:36:27