如何修改正则以匹配任意顺序的img的src、alt、title属性?
解决方案
一、修改正则表达式支持任意属性顺序
你的原正则只能捕获src之后的alt/title属性,且无法区分是alt还是title。可以调整正则,分别独立捕获src、alt、title三个属性,不管它们在标签内的顺序:
preg_match_all('#<img\s+[^>]*?(?:src="([^"]*)")?[^>]*?(?:alt="([^"]+)")?[^>]*?(?:title="([^"]+)")?[^>]*>#is', $url_contents, $image_matches);
捕获结果说明:
$image_matches[1]:所有匹配到的src属性值数组$image_matches[2]:所有匹配到的alt属性值数组$image_matches[3]:所有匹配到的title属性值数组
如果需要确保只匹配包含src的img标签,可以添加正向预查限制:
preg_match_all('#<img\s+(?=[^>]*src="[^"]*")[^>]*?(src="([^"]*)")?[^>]*?(alt="([^"]+)")?[^>]*?(title="([^"]+)")?[^>]*>#is', $url_contents, $image_matches);
二、更准确的HTML解析方案
正则匹配HTML天生存在局限性(比如无法处理属性内的转义字符、不规范的标签写法),更可靠的方法是使用PHP内置的DOM解析器:
$dom = new DOMDocument(); // 关闭HTML解析错误提示(兼容不规范的HTML代码) libxml_use_internal_errors(true); $dom->loadHTML($url_contents); libxml_clear_errors(); $image_matches = []; $images = $dom->getElementsByTagName('img'); foreach ($images as $img) { $imgData = []; if ($img->hasAttribute('src')) { $imgData['src'] = $img->getAttribute('src'); } if ($img->hasAttribute('alt')) { $imgData['alt'] = $img->getAttribute('alt'); } if ($img->hasAttribute('title')) { $imgData['title'] = $img->getAttribute('title'); } // 只保留有src的图片数据 if (isset($imgData['src'])) { $image_matches[] = $imgData; } }
优势:
- 自动处理HTML语法细节,比如属性值的转义、不闭合的标签等
- 返回的是关联数组,能清晰区分每个属性的键值,不会出现正则捕获混淆的问题
- 扩展性更强,后续需要提取其他属性时只需添加对应判断
内容的提问来源于stack exchange,提问作者adrianTNT
相关产品推荐
相关产品推荐

