preg_replace 用于删除杂散结束标记的正则表达式

preg_replace regex to remove stray end tag

我有一个字符串,其中包含不同类型的 html 标签和内容,包括一些 <img> 元素。我试图将那些 <img> 元素包装在 <figure> 标记中。到目前为止使用这样的 preg_replace 效果很好:

preg_replace( '/(<img.*?>)/s','<figure></figure>',$content); 

但是,如果 <img> 标签有一个相邻的 <figcaption> 标签,结果会很丑陋,并且会为图形元素生成一个杂散的结束标签:

<figure id="attachment_9615">
<img class="size-full" src="http://www.example.com/pic.png" alt="name" width="1699" height="354" />
<figcaption class="caption-text"></figure>Caption title here</figcaption>
</figure> 

我尝试了一大堆 preg_replace 正则表达式变体来将 img-tag 和 figcaption-tag 包装在图中,但似乎无法正常工作。

我最近的尝试:

preg_replace( '/(<img.*?>)(<figcaption .*>*.<\/figcaption>)?/s',
'<figure"></figure>',
$content); 

正如其他人指出的那样,最好使用解析器,即 DOMDocument。以下代码在每个 img 周围包装一个 <figure> 标记,其中下一个兄弟是 <figcaption>:

<?php

$html = <<<EOF
<html>
    <img class="size-full" src="http://www.example.com/pic.png" alt="name" width="1699" height="354" />
    <figcaption class="caption-text">Caption title here</figcaption>

    <img class="size-full" src="http://www.example.com/pic.png" alt="name" width="1699" height="354" />

    <img class="size-full" src="http://www.example.com/pic.png" alt="name" width="1699" height="354" />
    <figcaption class="caption-text">Caption title here</figcaption>
</html>
EOF;

$dom = new DOMdocument();
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);

# get all images
$imgs = $xpath->query("//img");

foreach ($imgs as $img) {
    if ($img->nextSibling->tagName == 'figcaption') {

        # create a new figure tag and append the cloned elements
        $figure = $dom->createElement('figure');
        $figure->appendChild($img->cloneNode(true));
        $figure->appendChild($img->nextSibling->cloneNode(true));

        # insert the newly generated elements right before $img
        $img->parentNode->insertBefore($figure, $img);

        # and remove both the figcaption and the image from the DOM
        $img->nextSibling->parentNode->removeChild($img->nextSibling);
        $img->parentNode->removeChild($img);

    }
}
$dom->formatOutput=true;
echo $dom->saveHTML();

参见a demo on ideone.com

要在 所有 图像周围添加 <figure> 标签,您可能需要添加 else分支机构:

} else {
    $figure = $dom->createElement('figure');
    $figure->appendChild($img->cloneNode(true));
    $img->parentNode->insertBefore($figure, $img);

    $img->parentNode->removeChild($img);
}