通过preg_match_all PHP函数从html代码字符串中提取img标记

时间:2016-12-27 14:24:12

标签: php html preg-match-all

我有一些HTML代码并从中提取 img src 属性。 进入html字符串有一些像这样的img:

<img src="http://www.pecso.it/wp-content/uploads/2016/12/10_WRAS.png">

我尝试使用以下PHP代码执行此操作:

$description = wpautop($this->data->description);
$description = preg_replace("/\[[^\]]+\]/", '', $description);
     if (preg_match_all("<img src=(.*?)>", $description, $match)) {
          echo match;
            };

,结果为NULL。

请帮帮我吗?

1 个答案:

答案 0 :(得分:1)

不要在html上使用正则表达式!

使用dom解析器,因为它更麻烦。

$html = file_get_contents("you_file.html");

$dom  = new \DOMDocument();
$dom->loadHTML($html);

$dom->preserveWhiteSpace = false;

$images = [];
foreach ($dom->getElementsByTagName('img') as $image) {
    $images[] = $image->getAttribute('src');
}

修改

您正在使用wpautop功能来清理说明。 根据该文档,它需要The text to be formatted.作为第一个参数。 所以首先要确保它确实保留了参数中的图像标记。

我认为标签会被保留。看看正则表达式本身,我发现它匹配得太少了。

您在资格组中匹配.*??表示使用延迟匹配,这意味着根据需要匹配少量字符。 因此.*将匹配任何字符,零或更多。 ?将根据需要匹配。

var_dump $match的{​​{1}}中,我发现它找到了一个匹配项。

array (size=2)   0 => 
    array (size=1)
      0 => string 'img src=' (length=8)   1 => 
    array (size=1)
      0 => string '' (length=0)

然而,第一个匹配组的大小为0.由于惰性匹配。 我假设和内部PHP错误。它应该匹配最多>,因为这也是正则表达式的一部分。 但似乎php忽略了这一部分。

如果您将捕获组更改为.+?,则第一个组将包含一个"字符。由于+表示“一个或多个”字符。

解决方案是更改代码,使其包含引号。

if (preg_match_all("<img src=\"(.*?)\">", $description, $match)) {

这匹配所需的图片链接:

http://www.pecso.it/wp-content/uploads/2016/12/10_WRAS.png

我建议尝试使用DOMDocument方法,因为这个代码更可能更稳定和可扩展。 如果你想了解正则表达式,解析html可能不是最好的开始。

所有这些代码都是使用php 5.4进行测试的,对于较新的版本可能会有所不同!