我想删除在内容结尾处未正确关闭的所有元素,例如在下面的测试中
commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea
voluptate velit esse quam nihil molestiae consequatur,
vel illum qui dolorem eum fugiat quo voluptas nulla
pariatur? <a rel="nofollow" class="underline"
我想删除
<a rel="nofollow" class="underline"
或没有结束标记的元素
<h2>sample text
或任何其他未在最后正确关闭的html元素。
答案 0 :(得分:4)
我写了一个应该做你想做的功能。我们的想法是首先用####
模式替换所有有效的标记序列。然后正则表达式将删除从第一个<
到字符串结尾的所有内容。之后,有效的标签序列被放回缓冲区(如果该部分由于该部分之前的无效标签而未被删除)。
太糟糕了,我无法添加键盘,因为键盘使用的PHP版本似乎不支持递归正则表达式。我用PHP 5.3.5进行了测试。
<强> PHP 强>
function StripUnclosedTags($input) {
// Close <br> tags
$buffer = str_ireplace("<br>", "<br/>", $input);
// Find all matching open/close HTML tags (using recursion)
$pattern = "/<([\w]+)([^>]*?) (([\s]*\/>)| (>((([^<]*?|<\!\-\-.*?\-\->)| (?R))*)<\/\\1[\s]*>))/ixsm";
preg_match_all($pattern, $buffer, $matches, PREG_OFFSET_CAPTURE);
// Mask matching open/close tag sequences in the buffer
foreach ($matches[0] as $match) {
$ofs = $match[1];
for ($i = 0; $i < strlen($match[0]); $i++, $ofs++)
$buffer[$ofs] = "#";
}
// Remove unclosed tags
$buffer = preg_replace("/<.*$/", "", $buffer);
// Put back content of matching open/close tag sequences to the buffer
foreach ($matches[0] as $match) {
$ofs = $match[1];
for ($i = 0; $i < strlen($match[0]) && $ofs < strlen($buffer); $i++, $ofs++)
$buffer[$ofs] = $match[0][$i];
}
return $buffer;
}
$str = 'commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate '
.'velit esse<br> quam nihil molestiae consequatur, vel illum qui dolorem eum '
.'fugiat quo voluptas nulla pariatur? '
.'<a href="test">test<p></p></a><span>test<p></p>bla';
var_dump(StripUnclosedTags($str));
<强>输出强>
string 'commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea
voluptate velit esse<br/> quam nihil molestiae consequatur,
vel illum qui dolorem eum fugiat quo voluptas nulla
pariatur? <a href="test">test<p></p></a>' (length=226)