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

时间:2009-07-28 20:35:54

标签: php html regex

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

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

问题:如何获得所有出现的匹配。更重要的是,具体来说,我如何获得img标记源(src =?)。

示例:

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

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

我知道这可以通过正则表达式实现,但我无法理解它。

非常感谢任何帮助。

10 个答案:

答案 0 :(得分:40)

虽然正则表达式可以适用于各种各样的任务,但我发现解析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属性。

可以设计一个正则表达式来实现相同的目标但是会限制它会强制alt属性位于src之后或相反的​​目标,并克服此限制会增加正则表达式的复杂性。

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

<\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;
}

答案 1 :(得分:12)

使用它,更有效:

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

答案 2 :(得分:7)

这对我有用:

preg_match('@<img.+src="(.*)".*>@Uims', $html, $matches);
$src = $matches[1];

答案 3 :(得分:5)

我假设你的所有src =都在“url

附近
<img[^>]+src=\"([^\"]+)\"

此处发布的其他答案会对您的代码提出其他答案

答案 4 :(得分:2)

我同意Andrew Moore的观点。使用DOM要好得多。 HTML DOM图像集合将返回对所有图像对象的引用。

让我们在你的标题中说,

<script type="text/javascript">
    function getFirstImageSource()
    {
        var img = document.images[0].src;
        return img;
    }
</script>

然后在你的身体里,

<script type="text/javascript">
  alert(getFirstImageSource());
</script>

这将返回第一个图像源。你也可以沿着(在头部)

的路线循环它们
function getAllImageSources()
    {
        var returnString = "";
        for (var i = 0; i < document.images.length; i++)
        {
            returnString += document.images[i].src + "\n"
        }
        return returnString;
    }

(在体内)

<script type="text/javascript">
  alert(getAllImageSources());
</script>

如果您使用JavaScript执行此操作,请记住您无法在标题中的图像集合中循环运行函数。换句话说,你不能做这样的事情,

<script type="text/javascript">
    function getFirstImageSource()
    {
        var img = document.images[0].src;
        return img;
    }
    window.onload = getFirstImageSource;  //bad function

</script>

因为这不起作用。执行标题时未加载图像,因此您将获得空结果。

希望这可以在某种程度上提供帮助。如果可能的话,我会使用DOM。你会发现你已经完成了很多工作。

答案 5 :(得分:2)

我不知道你是否必须使用正则表达式来获得结果。如果没有,你可以尝试使用simpleXML和XPath,这对你的目标来说更可靠:

首先,将HTML导入DOM文档对象。如果您收到错误,请关闭此部分的错误,并确保之后重新打开它们:

 $dom = new DOMDocument();
 $dom -> loadHTMLFile("filename.html");

接下来,将DOM导入simpleXML对象,如下所示:

 $xml = simplexml_import_dom($dom);

现在,您可以使用一些方法将所有图像元素(及其属性)放入数组中。 XPath是我喜欢的,因为我用它遍历DOM会有更好的运气:

 $images = $xml -> xpath('//img/@src');

现在可以将此变量视为图像网址数组:

 foreach($images as $image) {
    echo '<img src="$image" /><br />
    ';
  }

Presto,你的所有图像,没有脂肪。

以下是上述的非注释版本:


 $dom = new DOMDocument();
 $dom -> loadHTMLFile("filename.html");

 $xml = simplexml_import_dom($dom);

 $images = $xml -> xpath('//img/@src');

 foreach($images as $image) {
    echo '<img src="$image" /><br />
    ';
  }

答案 6 :(得分:2)

我真的认为你无法用正则表达式预测所有案例。

最好的方法是使用带PHP5 class DOMDocument和xpath的DOM。这是做你想做的最干净的方式。

$dom = new DOMDocument();
$dom->loadHTML( $htmlContent );
$xml = simplexml_import_dom($dom);
$images = $xml -> xpath('//img/@src');

答案 7 :(得分:1)

你可以试试这个:

preg_match_all("/<img\s+src=\"(.+)\"/i", $html, $matches);
foreach ($matches as $key=>$value) {
    echo $key . ", " . $value . "<br>";
}

答案 8 :(得分:1)

由于您并不担心验证HTML,因此您可能首先尝试在文本上使用strip_tags()来清除大部分内容。

然后你可以搜索像

这样的表达式
"/\<img .+ \/\>/i"

反斜杠会转义特殊字符,例如&lt;,&gt;,/。 。+坚持img标签中有任何一个或多个字符 您可以通过在括号周围加上括号来捕获部分表达式。例如(。+)捕获img标记的中间部分。

当您确定要特定捕获的中间部分时,可以将(。+)修改为更具体的内容。

答案 9 :(得分:0)

<?php    
/* PHP Simple HTML DOM Parser @ http://simplehtmldom.sourceforge.net */

require_once('simple_html_dom.php');

$html = file_get_html('http://example.com');
$image = $html->find('img')[0]->src;

echo "<img src='{$image}'/>"; // BOOM!

PHP Simple HTML DOM Parser将在几行代码中完成工作。