【问题标题】:How can i replace a multiple img-elements with plain text?如何用纯文本替换多个 img 元素?
【发布时间】:2018-03-26 11:53:59
【问题描述】:

我想创建一个输出文本过滤器,将 DOM 中的所有 <img> 元素替换为以下文本“no images allowed”。

即:如果用户创建此 HTML 标记:

<p><img src="/image.jpg" /></p>

呈现以下 HTML:

<p>no images allowed</p>

请注意,我不能使用preg_replace。问题很简单,我需要解析 DOM 以找到禁止使用的图像。

感谢this answer,我发现getElementsByTagName()返回“live”迭代器,所以你需要两个步骤,所以我有了这个:

foreach ($elements as $element) {
  $domArray[] = $element;
  $src= $element->getAttribute('src');
  $frag= $dom->createElement('p');
  $frag->nodeValue = 'no images allowed';
  $element->parentNode->appendChild($frag);
}
// loop through the array and delete each node
$nodes = iterator_to_array($dom->getElementsByTagName('img'));
foreach ($nodes as $node) {
  $node->parentNode->removeChild($node);
}
$newtext = $dom->saveHTML();

几乎做我想做的事,但我明白了:

<p><p>no images allowed</p></p>

【问题讨论】:

  • 如果用户创建了一个&lt;p&gt; 元素,其中包含&lt;img&gt; 和一些文本或其他元素,会发生什么?
  • @GUIDO,按预期创建&lt;p&gt;-element 工作(请参阅更新的问题)。它正在摆脱问题所在的&lt;img&gt;-元素。

标签: php html dom domdocument


【解决方案1】:

我会用 xpath 获取元素,然后用新创建的文本节点替换。

$xp = new DOMXPath($dom);
$elements = $xp->query('//img');
foreach ($elements as $element) {
  $frag= $dom->createTextNode('no images allowed');
  $element->parentNode->insertBefore($frag, $element);
  $element->parentNode->removeChild($element);
}
echo $dom->saveHtml();

在这里演示:http://codepad.org/w9uj0ez9

【讨论】:

  • 很好的答案!而且比我尝试解决它的尝试更简单。
【解决方案2】:

要删除 HTML 自封闭的 img 标签,您可以使用简单的正则表达式:

<?php

function no_images_allowed($text) {
    return preg_replace('/<img[^>]*>/', 'no images allowed', $text);
}

print no_images_allowed('<p><img src="/image.jpg" /></p>');

它更简单,应该更高效,你不需要遍历每个 DOM 元素,只处理纯文本。

上例中的正则表达式仅适用于自封闭的 img 标签:

<img src="..."/>
<img src="...">

请注意,它不适用于例如:

<img src="..."></img>
<IMG SRC="..."/>
<img src="...">invalid content</img>

如果您想包含所有可能的情况(甚至是无效的情况),则应修改建议的正则表达式。

【讨论】:

  • 我也会建议这种方法。
  • 你见过这个:stackoverflow.com/questions/1732348/… 吗? &lt;img alt="&gt;" src="..."&gt;呢?
  • 我同意正则表达式查询不能代替真正的 DOM 解析,但我认为没有必要仅解析整个 DOM 以删除自封闭的 img 标签。这一切都取决于你需要什么。对于更复杂的 DOM 修改,我不建议使用正则表达式。
  • 要替换 every 图像标签,preg_replace 会很好用。但是,我真的很想根据属性的值进行条件替换,所以我需要 tp 解析 DOM。
  • 在边缘,我用 preg_replace 和 DOMXPath 解决方案过滤了这个页面源,第一个花了 0.00027ms,后者 0.00261ms,preg_replace 快了 10 倍。正则表达式的缺点是它不适用于无效的 HTML 或更复杂的情况。
猜你喜欢
  • 1970-01-01
  • 2018-07-18
  • 2020-01-08
  • 2012-10-24
  • 1970-01-01
  • 2021-09-29
  • 2011-10-11
  • 2014-10-30
  • 2011-07-22
相关资源
最近更新 更多