HTML操作:匹配前X个HTML标记并移动它们


HTML manipulation: Match the first X number of HTML tags and move them

假设我有这样的代码:

<img src="001">
<img src="002">
<p>Some content here.</p>
<img src="003">

我现在要做的是匹配前两个图像(001和002)并将该部分代码存储在变量中。我不想对第三张图片做任何事情。

我使用了类似preg_match_all('/<img .*>/', $result);的东西,但它显然匹配所有的图像。不仅仅是那些出现在代码顶部的。如何修改正则表达式以只选择位于代码顶部的图像。

我想做的是现在。我有<h2>标签与标题在一个变量和上面的代码在第二个。我想将第一个X图像移动到<h2>标签之前或在第一个X图像之后插入<h2>标签。所有这些都在后端PHP中。用CSS来做会很有趣,但是flexbox还没有。

你需要把问题分开来解决。这里有两个主要部分:

  1. 将HTML划分为顶部和底部部分。
  2. 做DOMDocument操作上(两者?)HTML字符串。

我们就这么做吧:

第一部分实际上很简单。假设所有的行分隔符都是"'n",空行实际上是空行"'n'n"。这是一个简单的字符串操作:

list($top, $bottom) = explode("'n'n", $html, 2);

这已经解决了第一部分。Top html在$top中,其余的我们实际上不需要关心的是存储在$bottom中。

让我们继续第二部分。

通过简单的DOMDocument操作,您现在可以获得所有图像的列表:

$topDoc = new DOMDocument();
$topDoc->loadHTML($top);
$topImages = $topDoc->getElementsByTagname('img');

你现在唯一需要做的就是从它的父图像中删除每个图像:

$image->parentNode->removeChild($image);

然后插入<h2>元素之前:

$anchor = $topDoc->getElementsByTagName('h2')->item(0);
$anchor->parentNode->insertBefore($image, $anchor);

你很好。完整代码示例:

$html = <<<HTML
<h2>Title here</h2>
<img src="001">
<p>Some content here. (for testing purposes)</p>
<img src="002">
<h2>Second Title here (for testing purposes)</h2>
<p>Some content here.</p>
<img src="003">
HTML;
list($top, $bottom) = explode("'n'n", $html, 2);
$topDoc = new DOMDocument();
$topDoc->loadHTML($top);
$topImages = $topDoc->getElementsByTagname('img');
$anchor = $topDoc->getElementsByTagName('h2')->item(0);
foreach($topImages as $image) {
    $image->parentNode->removeChild($image);
    $anchor->parentNode->insertBefore($image, $anchor);
}
foreach($topDoc->getElementsByTagName('body')->item(0)->childNodes as $child)
    echo $topDoc->saveHTML($child);
echo $bottom;
输出:

<img src="001"><img src="002"><h2>Title here</h2>
<p>Some content here. (for testing purposes)</p>
<h2>Second Title here (for testing purposes)</h2>
<p>Some content here.</p>
<img src="003">