[英]Regular expression to match content until multi-character string
我的輸入有缺陷,看起來像這樣......
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>
但是由於簡單的正則表達式只查找<
,它在<b>
處停止並吐出:
<p>foo </p><b>bold</b><p>bar</p> <!-- oops -->
那么如何重寫正則表達式以匹配<p
? 顯然答案涉及消極的前瞻,但這對我來說有點太深了。
(在不可避免的“你不能用正則表達式解析 HTML”之前,評論說,輸入不是隨機的 HTML,而是僅用標簽<p>
、 <a>
、 <b>
和<i>
注釋的純文本,以及a/b/i 不能嵌套。)
我認為你實際上想要積極的前瞻。 這真的不錯:
/^([^<]+)(?=<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>"
抱歉,在我的原始帖子中不夠清楚:我的期望是“foo bold”位也會被包裹在一個新的
p
標簽中,但這並沒有發生。此外,有時輸入根本沒有
p
標簽(只是普通的foo
),這也應該 map 到<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>"
通過組合re1
和re2
可以編寫一個等效的正則表達式:
/^(.+?(?=<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>"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.