【问题标题】:Using regex to wrap images in tags使用正则表达式将图像包装在标签中
【发布时间】:2012-04-26 09:33:42
【问题描述】:

我一直在使用正则表达式将我的图像包装在 标记中并更改它们的路径等。 我知道使用 dom 会更好,阅读了很多关于包装的主题,但我无法理解如何。

这是我正在使用的:

$comments = (preg_replace('@(<img.+src=[\'"]/uploads/userdirs/admin)(?:.*?/)(.+?)\.(.+?)([\'"].*?>)@i', '<a class="gallery" rel="'.$pagelink.'" href=/uploads/userdirs/'.$who.'/$2.$3>$1/mcith/mcith_$2.$3$4</a>', $comments));

它成功地将每个图像包装在我想要的标签中。但前提是提供的字符串 ($cmets) 具有正确的标记。

<p><img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960" /></p>
<p><img src="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024" /></p>

当这样呈现时,它可以工作。我正在使用 tinymce,所以当我使用 enter 进行换行时,它会包含在 中。但是当我不这样做时,当我只是一个接一个地插入图像以使 HTML 看起来像这样时,它不会:

<p><img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960" /><img src="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024" /></p>

它会将这 2 个图像包装在同一个 标记中。使输出看起来像这样:

<p><a class="gallery" rel="test" href="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg">
<img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960">
<img src="/uploads/userdirs/admin/mcith/mcith_100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024">
</a></p>

这是错误的。我想要的输出是这样的:

<p><a class="gallery" rel="test2" href="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg"><img src="/uploads/userdirs/admin/mcith/mcith_100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024"></a></p>
<p><a class="gallery" rel="test2" href="/uploads/userdirs/admin/1154686260226.jpg"><img src="/uploads/userdirs/admin/mcith/mcith_1154686260226.jpg" alt="" width="1280" height="800"></a></p>

【问题讨论】:

  • 如果您不了解如何以正确的方式进行操作,那么您可能应该询问如何以正确的方式进行操作,而不是讨论如何以错误的方式工作。
  • 我正在这样做。无论哪种方式都对我有用..如果有人可以将我推向 dom 重写的正确方向,我会很高兴 =)

标签: php html regex


【解决方案1】:

我遗漏了一些细节,但下面是我使用 DOMDocument 的方法:

$s = <<<EOM
<p><img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960" /></p>
<p><img src="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024" /></p>
EOM;

$d = new DOMDocument;
$d->loadHTML($s);

foreach ($d->getElementsByTagName('img') as $img) {
    $img_src = $img->attributes->getNamedItem('src')->nodeValue;
    if (0 === strncasecmp($img_src, '/uploads/userdirs/admin', 23)) {
        $a = $d->createElement('a');

        $a->setAttribute('class', 'gallery');
        $a->setAttribute('rel', 'whatever');
        $a->setAttribute('href', '/uploads/userdirs/username/' . $img_src);

        // disconnect image tag from parent
        $img->parentNode->replaceChild($a, $img);

        // and move to anchor
        $a->appendChild($img);
    }
}

echo $d->saveHTML();

【讨论】:

  • 非常感谢!这对我有很大帮助!它有效,无论我扔什么都会重写。试图从中提取文件名,以便我可以这样做:$a-&gt;setAttribute('href', '/uploads/userdirs/username/thumbnail/' . $img_filename); domdocument 可以这样做吗?
  • 我在循环中声明了一个变量$img_src,其中包含原始图像位置的值。这是你需要的吗?
  • 是的!我现在使用 pathinfo 来 yoink 只是文件名 =) 非常感谢你帮助我理解 domdocument。
【解决方案2】:

您应该将正则表达式中的.* 更改为[^&gt;]*。后者意味着:除&gt; 之外的任何字符。因为正则表达式得到尽可能长的匹配。如果没有这个附加条件,最终会匹配到两个 &lt;img&gt;

【讨论】:

  • 嗯,像这样? $comments = (preg_replace('@(&lt;img.+src=[\'"]/uploads/userdirs/admin)(?:[^&gt;]*.?/)(.+?)\.(.+?)([\'"][^&gt;]*.?&gt;)@i', '&lt;a class="gallery" rel="'.$pagelink.'" href=/uploads/userdirs/'.$who.'/$2.$3&gt;$1/mcith/mcith_$2.$3$4&lt;/a&gt;', $comments)); 我使用它得到了相同的输出。
  • 添加一些 [^"]+ 说明符有帮助:@(&lt;img[^&gt;]+src=['"]/uploads/userdirs/admin)(?:[^"]*?/)([^"]+?).([^"]+?)(['"][^&gt;]*?&gt;)@i
  • 但是正如上面所说,使用一些 HTML 解析器作为 DOM 会更安全。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-18
  • 1970-01-01
  • 2014-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多