【问题标题】:Regular expression to match content until multi-character string正则表达式匹配内容直到多字符串
【发布时间】:2011-09-15 05:01:27
【问题描述】:

我的输入有缺陷,看起来像这样...

foo<p>bar</p>

我想对其进行规范化以将前导文本包装在 p 标签中:

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

&lt;p&gt;$1&lt;/p&gt; 的正则表达式替换/^([^&lt;]+)/ 很容易。问题是,有时前导块包含 p 以外的标签,如下所示:

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

这应该将整个块包装在一个新的 p 中:

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

但由于简单的正则表达式只查找&lt;,它在&lt;b&gt; 处停止并吐出:

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

那么我该如何重写正则表达式以匹配&lt;p?显然答案涉及到否定前瞻,但this 对我来说有点太深了。

(在不可避免的“你不能用正则表达式解析HTML!”评论之前,输入不是随机的HTML,而是只用标签&lt;p&gt;&lt;a&gt;&lt;b&gt;和@987654335注释的纯文本@, 和 a/b/i 不能嵌套。)

【问题讨论】:

  • +1 只为最后一句话。

标签: javascript regex html-parsing regex-negation


【解决方案1】:

我认为您实际上希望 积极 向前看。确实不错:

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

您只想确保&lt; 之后的内容是p,但您不想实际使用&lt;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),它也应该映射到&lt;p&gt;foo&lt;/p&gt;

我发现最简单的方法是使用 2 个单独的正则表达式,/^(.+?(?=&lt;p))//^([^&lt;]+)/

> 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 来编写一个等效的正则表达式:
/^(.+?(?=&lt;p)|[^&lt;]+)/

> 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>"

【讨论】:

  • 抱歉,在我的原始帖子中不够清楚:我的预期是“foo bold”位也会被包裹在一个新的 p 标签中,但这并没有发生。
  • 另外,偶尔会有没有p标签的输入(只是简单的foo),并且应该也映射到&lt;p&gt;foo&lt;/p&gt;
  • 基本思想很简单,文本应该始终包含在段落中。两个正则表达式样式效果很好,谢谢!
猜你喜欢
  • 1970-01-01
  • 2017-09-02
  • 2020-03-16
  • 2013-09-06
  • 1970-01-01
  • 2011-09-26
  • 1970-01-01
  • 2015-09-30
  • 1970-01-01
相关资源
最近更新 更多