[英]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.