使用正则表达式从html代码中提取第一个图像源?

2022-08-30 19:26:37

我想知道如何实现这一目标。

假设:有很多html代码包含表格,div,图像等。

问题:如何获取所有事件的匹配项。更确切地说,我如何获得img标签源(src = ?)。

例:

<img src="http://example.com/g.jpg" alt="" />

在这种情况下,我该如何打印出 http://example.com/g.jpg。我想假设正如我所提到的html代码中还有其他标签,并且可能有多个图像。是否可以在html代码中拥有所有图像源的数组?

我知道这可以通过正则表达式或其他方式实现,但我无法掌握它的窍门。

任何帮助都非常感谢。


答案 1

虽然正则表达式可以很好地用于各种任务,但我发现在解析HTML DOM时它通常不足。HTML的问题在于,文档的结构变化很大,很难准确地提取标签(准确地说,我的意思是100%的成功率,没有误报)。

我建议你做的是使用DOM解析器,如SimpleHTML,并按如下方式使用它:

function get_first_image($html) {
    require_once('SimpleHTML.class.php')

    $post_html = str_get_html($html);

    $first_img = $post_html->find('img', 0);

    if($first_img !== null) {
        return $first_img->src;
    }

    return null;
}

有些人可能认为这有点过分,但最终,它将更容易维护,并且还允许更多的可扩展性。例如,使用DOM解析器,我还可以获取alt属性。

正则表达式可以设计成实现相同的目标,但会受到限制,以至于它会强制属性在后面或相反的位置,并且克服这种限制会增加正则表达式的复杂性。altsrc

此外,请考虑以下事项。要使用正则表达式正确匹配标记并仅获取属性(在组 2 中捕获),您需要以下正则表达式:<img>src

<\s*?img\s+[^>]*?\s*src\s*=\s*(["'])((\\?+.)*?)\1[^>]*?>

再说一遍,如果出现以下情况,上述操作可能会失败:

  • 属性或标记名称采用大写形式,不使用 i 修饰符。
  • 属性两边不使用引号。src
  • 然后,另一个属性在其值中的某个位置使用该字符。src>
  • 我没有预见到的其他一些原因。

所以同样,不要使用正则表达式来解析dom文档。


编辑:如果你想要所有的图像:

function get_images($html){
    require_once('SimpleHTML.class.php')

    $post_dom = str_get_dom($html);

    $img_tags = $post_dom->find('img');

    $images = array();

    foreach($img_tags as $image) {
        $images[] = $image->src;
    }

    return $images;
}

答案 2

使用这个,更有效:

preg_match_all('/<img [^>]*src=["|\']([^"|\']+)/i', $html, $matches);
foreach ($matches[1] as $key=>$value) {
    echo $value."<br>";
}

例:

$html = '
<ul>     
  <li><a target="_new" href="http://www.manfromuranus.com">Man from Uranus</a></li>       
  <li><a target="_new" href="http://www.thevichygovernment.com/">The Vichy Government</a></li>      
  <li><a target="_new" href="http://www.cambridgepoetry.org/">Cambridge Poetry</a></li>      
  <img width="190" height="197" border="0" align="right" alt="upload.jpg" title="upload.jpg" class="noborder" src="value1.jpg" />
  <li><a href="http://www.verot.net/pretty/">Electronaut Records</a></li>      
  <img width="190" height="197" border="0" align="right" alt="upload.jpg" title="upload.jpg" class="noborder" src="value2.jpg" />
  <li><a target="_new" href="http://www.catseye-crew.com">Catseye Productions</a></li>     
  <img width="190" height="197" border="0" align="right" alt="upload.jpg" title="upload.jpg" class="noborder" src="value3.jpg" />
</ul>
<img width="190" height="197" border="0" align="right" alt="upload.jpg" title="upload.jpg" class="noborder" src="res/upload.jpg" />
  <li><a target="_new" href="http://www.manfromuranus.com">Man from Uranus</a></li>       
  <li><a target="_new" href="http://www.thevichygovernment.com/">The Vichy Government</a></li>      
  <li><a target="_new" href="http://www.cambridgepoetry.org/">Cambridge Poetry</a></li>      
  <img width="190" height="197" border="0" align="right" alt="upload.jpg" title="upload.jpg" class="noborder" src="value4.jpg" />
  <li><a href="http://www.verot.net/pretty/">Electronaut Records</a></li>      
  <img src="value5.jpg" />
  <li><a target="_new" href="http://www.catseye-crew.com">Catseye Productions</a></li>     
  <img width="190" height="197" border="0" align="right" alt="upload.jpg" title="upload.jpg" class="noborder" src="value6.jpg" />
';   
preg_match_all('/<img .*src=["|\']([^"|\']+)/i', $html, $matches);
foreach ($matches[1] as $key=>$value) {
    echo $value."<br>";
} 

输出:

value1.jpg
value2.jpg
value3.jpg
res/upload.jpg
value4.jpg
value5.jpg
value6.jpg

推荐