如何将 html 标签替换为存储在 php 数组中的其他标签


How to replace html tags with other tags stored in a php array?

我在php变量中存储了以下html代码:

<p>This is a sample paragraph</p>
   <img src="img/1.jpg">
<h1>This is my header</h1>
   <img src="img/2.jpg">
<p>I hope someone can help me</p>
   <img src="img/3.jpg">

我有一个 php 数组,它有三个元素,与 html 字符串中的图像元素一样多:

Array(3){
         [0]<img src="img/new1.jpg">
         [1]<img src="img/new2.jpg">
         [2]<img src="img/new3.jpg">
}

我正在尝试编写一个函数,该函数将用第一个数组元素替换 html 字符串中的第一个 img 标签,用数组中的第二个元素替换第二个,用数组中的第三个元素替换第三个。所以最后我得到这个:

<p>This is a sample paragraph</p>
    <img src="img/new1.jpg">
    <h1>This is my header</h1>
   <img src="img/new2.jpg">
    <p>I hope someone can help me</p>
    <img src="img/new3.jpg">

相信我,我不知道该怎么做。如果我有一个想法,我会尝试,但问题是我无法得出解决这个问题的任何逻辑。任何帮助都会很棒。

如果您能够让新的图像标签数组仅包含路径/文件信息而不是全新的 HTML 标签,那么类似于以下内容的内容应该可以工作:

$html = <<<'HTML'
<p>This is a sample paragraph</p>
   <img src="img/1.jpg">
<h1>This is my header</h1>
   <img src="img/2.jpg">
<p>I hope someone can help me</p>
   <img src="img/3.jpg">
HTML;
$newImages = ['img/new1.jpg', 'img/new2.jpg', 'img/new3.jpg'];
$dom = new DOMDocument;
$dom->loadHTML($html);
$images = $dom->getElementsByTagName('img');
for ($i = 0; $i < $images->length; $i++)
    $images->item($i)->setAttribute('src', $newImages[$i]);
// Your updated HTML is now in $html    
$html = $dom->saveHTML();

注意:您可以使用 preg_replacestr_replace 将新图像数组修改为仅包含路径/图像。

根据您的

回复和以下答案的改进请求进行更新:

  • 我在之前的回复中忘记了这一点,但从 PHP 5.4 和 Libxml 2.6 开始,loadHTML()接受 Libxml 参数。你可以删除所有str_replace()的东西(见代码)。
  • 如果参数是一个简单的字符串,则无需将参数复制到局部变量$content因为它无论如何都会按值传递(原始字符串不会被修改)。
  • 在这种情况下,我不会使用 @ 来抑制错误,而是使用 libxml_use_internal_errors 和 libxml_get_errors。
  • 正如我在评论中提到的,我没有看到$imagetag_arr被传递给函数、声明全局或$this前面。我已将其添加到函数的arg列表中,并具有更具描述性的名称。

更新的代码:

function replaceTags($content, $newImages)
{
    $dom = new DOMDocument();
    $dom->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    $images = $dom->getElementsByTagName('img');
    for ($i = 0; $i < $images->length; $i++)
    {
        $dom2 = new DOMDocument();
        $dom2->loadHTML($newImages[$i]);
        $newImg = $dom2->getElementsByTagName('img')
                       ->item(0);
        $images->item($i)->setAttribute('src', $newImg->getAttribute('src'));
    }
    return $dom->saveHTML();
}

$a=Array (
    'img/1.jpg'=>'img/new1.jpg',
    'img/2.jpg'=>'img/new2.jpg',
    'img/3.jpg'=>'img/new3.jpg');
$replace=array_values($a);
$find=array_keys($a);
$html=str_replace($find, $replace, $html);

如果要在HTML对象树中的更高级别进行替换,则需要使用Dom解析器,否则会遇到以下问题:

<img
    src='img/1.jpg'
>

试试这个:

$source = <<<'EOD'
<p>This is a sample paragraph</p>
   <img src="img/1.jpg">
<h1>This is my header</h1>
   <img src="img/2.jpg">
<p>I hope someone can help me</p>
   <img src="img/3.jpg">
EOD;
$new = [
  '<img src="img/new1.jpg">',
  '<img src="img/new2.jpg">',
  '<img src="img/new3.jpg">',
];
$i = 0;
$result = preg_replace_callback(
  '/<img src="img'/[^.]+'.jpg">/',
  function($matches) use ($new, &$i) {
    return $new[$i++];
  },
  $source
);

它经过测试并且可以工作。
但也许有人可以找到一种更优雅的方式来使用$new$i

感谢大家的回答。我已经以某种方式结合了所有答案,并得出了以下解决方案。从编码的角度来看,这不是最好的,因为写了这个"业余"脚本,我真的对自己感觉不好。但它在所有条件下都有效。如果有人可以改进此代码,我将不胜感激。

$content是我的 html 字符串。$imagetag_arr 是带有新图像标记的数组。

 function replaceTags($content){
         $html = $content; //content is my html string.

        $dom = new DOMDocument;
        $dom->loadHTML($html);
        $images = $dom->getElementsByTagName('img');
        for ($i = 0; $i < $images->length; $i++) {
            $dom2 = new DOMDocument();
            @$dom2->loadHTML($imagetag_arr[$i]);
            $search = $dom2->getElementsByTagName('img');
            foreach ($search as $item) {
                $newsrc=$item->getAttribute('src');
            }
            $images->item($i)->setAttribute('src', $newsrc);
        }
    // my updated HTML is now in $html
    $html = $dom->saveHTML();

        //because I've saved it as html now the dom object is appending all the html
        //and body tags to my  $final result so I've replaced
       // them all with empty strings.I hate myself
      // for doing it like this.
        $finalhtml=preg_replace('/<![^>]+>/i','',$html);
        $finalhtml=str_replace('<html>','',$finalhtml);
        $finalhtml=str_replace('<body>','',$finalhtml);
        $finalhtml=str_replace('</body>','',$finalhtml);
        $finalhtml=str_replace('</html>','',$finalhtml);
        return $finalhtml;
    }
相关文章: