使用 preg_replace_callback() 从 HTML 字符串中提取所有图像

Posted

技术标签:

【中文标题】使用 preg_replace_callback() 从 HTML 字符串中提取所有图像【英文标题】:Using preg_replace_callback() to extract all images from a string of HTML 【发布时间】:2011-07-25 08:19:16 【问题描述】:

这里是棘手的 preg_replace_callback 函数 - 诚然,我不擅长 PRCE 表达式。

我正在尝试从 html 字符串中提取所有 img src 值,将 img src 值保存到数组中,并将 img src 路径替换为本地路径(不是远程路径)。即我可能有,周围有很多其他 HTML:

img src='http://www.mysite.com/folder/subfolder/images/myimage.png'

我想将 myimage.png 提取到一个数组中,另外将 src 更改为:

src='images/myimage.png'

可以吗?

谢谢

【问题讨论】:

Regex to change format of all img src attributes 的可能重复项 【参考方案1】:

是否需要使用正则表达式?使用 DOM 函数处理 HTML 通常更容易:

<?php

$domd = new DOMDocument();
libxml_use_internal_errors(true);
$domd->loadHTML(file_get_contents("http://***.com"));
libxml_use_internal_errors(false);

$items = $domd->getElementsByTagName("img");
$data = array();

foreach($items as $item) 
  $data[] = array(
    "src" => $item->getAttribute("src"),
    "alt" => $item->getAttribute("alt"),
    "title" => $item->getAttribute("title"),
  );


print_r($data);

【讨论】:

【参考方案2】:

您需要正则表达式吗?不必要。正则表达式是最易读的解决方案吗?可能不会——至少除非你精通正则表达式。扫描大量数据时,正则表达式是否更有效?当然,正则表达式在第一次出现时就被编译和缓存。正则表达式是否赢得了“最少的代码行”奖杯?

$string = <<<EOS
<html>
<body>
blahblah<br>
<img src='http://www.mysite.com/folder/subfolder/images/myimage.png'>blah<br>
blah<img src='http://www.mysite.com/folder/subfolder/images/another.png' />blah<br>
</body>
</html>
EOS;

preg_match_all("%<img .*?src=['\"](.*?)['\"]%s", $string, $matches);
$images = array_map(function ($element)  return preg_replace("%^.*/(.*)$%", 'images/$1', $element); , $matches[1]);

print_r($images);

两行代码,在 PHP 中很难削弱。它会产生以下$images 数组:

Array
(
  [0] => images/myimage.png
  [1] => images/another.png
)

请注意,这不适用于 5.3 之前的 PHP 版本,除非您将匿名函数替换为适当的函数。

【讨论】:

以上是关于使用 preg_replace_callback() 从 HTML 字符串中提取所有图像的主要内容,如果未能解决你的问题,请参考以下文章

preg_replace_callback函数

使用 preg_replace_callback 查找并替换具有可变数量参数的函数签名

将preg_replace()改写为preg_replace_callback()

从 preg_replace 到 preg_replace_callback

preg_replace_callback 正则替换回调方法用法,

如何将 preg_replace e 转换为 preg_replace_callback?