使用php删除重复的img标记

时间:2016-03-20 11:43:12

标签: php string

在这样的字符串中:

<body>
   <img src="specialpic" />
   <p>sometext</p><br>
   <img src="/somepic.png" />
   <img src="/somepic.png" />
   <p>someotherstuff</p>
   <img src="/anotherpic.png" />
   <img src="/anotherpic.png" />
</body>

如何删除每个重复的img标记,以便最终字符串如下所示?

<body>
   <img src="specialpic" />
   <p>sometext</p><br>
   <img src="/somepic.png" />
   <p>someotherstuff</p>
   <img src="/anotherpic.png" />
</body>

2 个答案:

答案 0 :(得分:1)

为此使用HTML解析器。请使用DOMDocument查看此示例。

初始化DOMDocument并加载您的HTML文件:

$dom = new DOMDocument();
libxml_use_internal_errors(1);
$dom->formatOutput = True;

$dom->loadHTML($html);

初始化两个空数组:$img将包含唯一的src值,$toDelete将包含要删除的重复节点:

$img = $toDelete = array();

使用<img>标记搜索所有节点:

$nodes = $dom->getElementsByTagName( 'img' );

对于每个找到的节点,将src属性与$img数组进行比较:如果找到,请将当前节点添加到$toDelete,否则将src值添加到{{1} }}:

$img

最后,执行foreach( $nodes as $node ) { $src = $node->getAttribute('src' ); if( in_array( $src, $img ) ) $toDelete[] = $node; else $img[] = $src; } 循环以删除找到的节点:

foreach

打印生成的HTML:

foreach( $toDelete as $node ) $node->parentNode->removeChild( $node );

请注意echo $dom->saveHTML(); 阵列的使用情况。从理论上讲,我们可以直接在第一个$toDelete内删除节点,但通过这种方式我们减少原始发现集的len,所以跳过下一个节点。

答案 1 :(得分:1)

虽然由于HTML的性质而不完全推荐,但根据您的问题,假设图像标签总是采用相同的格式,或者在比较时字符与字符完全相同,则可以使用子图案。 / p>

试试这个:

$input =<<<EOF
<body>
<img src="specialpic" />
<p>sometext</p><br>
<img src="/somepic.png" />
<img src="/somepic.png" />
<p>someotherstuff</p>
<img src="/anotherpic.png" />
<img src="/anotherpic.png" />
</body>
EOF;

$result = preg_replace('|(<img\s*src=.*?\s*/>\s*)\1*|s', '\1', $input);

结果应该是您所希望的确切输出。请在此处查看:https://3v4l.org/sbgDX

  • \s*将匹配任何空格
  • .*?是对
  • 之间任何字符的非贪婪匹配 模式参数中的
  • \1*表示子行模式重复0或更多,在换行后或匹配模式后的任何空格

来自this post的灵感。