一尘不染

关闭字符串中打开的HTML标记

php

情况是一个字符串,它导致如下所示:

<p>This is some text and here is a <strong>bold text then the post stop here....</p>

因为该函数返回文本的摘要(摘要),所以它在某些单词之后停止。在这种情况下,强标签没有关闭。但是整个字符串都包裹在一个段落中。

是否可以将上述结果/输出转换为以下内容:

<p>This is some text and here is a <strong>bold text then the post stop here....</strong></p>

我不知道从哪里开始。问题是..我在网上找到一个执行正则表达式的函数,但是它将结束标记放在字符串后面..因此它无法验证,因为我要在段落标记中使用所有打开/关闭标记。我发现的功能这样做是错误的:

<p>This is some text and here is a <strong>bold text then the post stop here....</p></strong>

我想知道标签可以是坚固的,斜体的。这就是为什么我不能追加功能并在功能中手动关闭它的原因。有什么模式可以帮我吗?


阅读 331

收藏
2020-05-29

共1个答案

一尘不染

这是我之前使用过的功能,效果很好:

function closetags($html) {
    preg_match_all('#<(?!meta|img|br|hr|input\b)\b([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
    $openedtags = $result[1];
    preg_match_all('#</([a-z]+)>#iU', $html, $result);
    $closedtags = $result[1];
    $len_opened = count($openedtags);
    if (count($closedtags) == $len_opened) {
        return $html;
    }
    $openedtags = array_reverse($openedtags);
    for ($i=0; $i < $len_opened; $i++) {
        if (!in_array($openedtags[$i], $closedtags)) {
            $html .= '</'.$openedtags[$i].'>';
        } else {
            unset($closedtags[array_search($openedtags[$i], $closedtags)]);
        }
    }
    return $html;
}

但是就我个人而言,我不会使用regexp而是使用Tidy之类的库来实现。这将类似于以下内容:

$str = '<p>This is some text and here is a <strong>bold text then the post stop here....</p>';
$tidy = new Tidy();
$clean = $tidy->repairString($str, array(
    'output-xml' => true,
    'input-xml' => true
));
echo $clean;
2020-05-29