【问题标题】:regex: put text outside <p> inside <p>正则表达式:将文本放在 <p> 外 <p> 内
【发布时间】:2010-08-12 12:15:49
【问题描述】:

我有一些损坏的 html 代码,我想用正则表达式修复。

html 可能是这样的:

<p>text1</p>
<p>text2</p>
text3
<p>text4</p>
<p>text5</p>

但也可以有更多的段落和其他 html 元素。

我想变成:

<p>text1</p>
<p>text2</p>
<p>text3</p>
<p>text4</p>
<p>text5</p>

这可以用正则表达式吗?如果这很重要,我正在使用 php。

【问题讨论】:

标签: regex html-parsing


【解决方案1】:

不,这对于正则表达式来说通常是个坏主意。正则表达式不进行状态解析。 HTML 有隐式标签,需要保留状态才能解析。

HTML 通常有很多怪癖。编写 HTML 解析器是很困难的,因为您不仅必须跟踪事情应该如何,而且还要考虑在野外看到的破坏行为。

正则表达式对于这项工作来说是错误的工具。

【讨论】:

  • 我明白了。我为它写了一个解析器,效果很好。谢谢:)
【解决方案2】:

http://htmlpurifier.org/可以帮到你吗?

【讨论】:

  • 啊,这可能有点矫枉过正,因为我只需要解决这个特定的问题,但我会再使用 htmlpurifier :)
【解决方案3】:

虽然正则表达式不是此类工作的最佳解决方案,但此代码适用于您提供的示例(它可能不是最佳的!)

<php>

$text = '<p>text1</p>
<p>text2</p>
text3
<p>text4</p>
<p>text5</p>';

$regex = '|(([\r\n ]*<p>[a-zA-Z0-9 \r\n]+</p>[\r\n ]*)+)([\r\n ]*[a-zA-Z0-9 ]+)(([\r\n ]*<p>[a-zA-Z0-9 \r\n]+</p>[\r\n ]*)+)|i';
$replacement = '${1}<p>${3}</p>${4}';
$replacedText =  preg_replace($regex, $replacement, $text);

echo $replacedText;
</php>

在替换字符串中,看到您使用匹配 1、3 和 4 来获得正确的子匹配!如果您希望能够捕获其他 HTML 标记,那么

,你可以使用这个正则表达式:

$regex = '|(([\r\n ]*<[a-z0-6]+>[a-zA-Z0-9 \r\n]+</[a-z0-6]+>[\r\n ]*)+)([\r\n ]*[a-zA-Z0-9 ]+)(([\r\n ]*<[a-z0-6]+>[a-zA-Z0-9 \r\n]+</[a-z0-6]+>[\r\n ]*)+)|i';

但要注意它可能会搞砸,因为结束标签可以匹配到不同的东西。

【讨论】:

  • 谢谢,我听从了不使用正则表达式的建议,但还是非常感谢!
猜你喜欢
  • 2013-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 2012-04-21
  • 1970-01-01
相关资源
最近更新 更多