假设我有这样的代码:
<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还没有。
你需要把问题分开来解决。这里有两个主要部分:
- 将HTML划分为顶部和底部部分。
- 做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">