在爬蟲、內容清洗、編輯器圖片遷移等場景中,常需從 HTML 字串中提取所有 <img> 標籤的 src 屬性值。本文提供一個健壯的正則模式,並講解邊界情況處理與效能優化技巧。
<?php
header("Content-type: text/html; charset=utf-8");
$html = '<p><img src="images/11111111.jpg" alt="美女" /></p>';
// 模式:匹配 img 標籤(大小寫不敏感),捕獲 src 引號內的內容,限制常見圖片副檔名
$pattern = '/<img[^>]*src=["\']([^"\']+\.(?:gif|jpg|jpeg|png|bmp|webp))["\'][^>]*>/i';
preg_match_all($pattern, $html, $matches);
echo "<pre>";
print_r($matches);
?>
輸出:
Array
(
[0] => Array ( [0] => <img src="images/11111111.jpg" alt="美女" /> )
[1] => Array ( [0] => images/11111111.jpg ) // 捕獲組 1 為我們要的 URL
)
| 片段 | 含義 |
|---|---|
/ ... /i | 分隔符 + i 忽略大小寫(匹配 <IMG>、<Img>) |
<img | 標籤開頭 |
[^>]* | 匹配除 > 外任意字符(屬性區),非貪婪 |
src=["\'] | 匹配 src= 後的單引號或雙引號 |
([^"\']+\.(?:gif|jpg|jpeg|png|bmp|webp)) | 捕獲組 1:非引號字符 + 點 + 圖片副檔名(非捕獲組 (?:...)) |
["\'] | 結尾引號 |
[^>]*> | 剩餘屬性至標籤閉合 |
$pattern = '/<img[^>]*src\s*=\s*(["\']?)([^"\'\s>]+\.(?:gif|jpg|jpeg|png|bmp|webp))\1[^>]*>/i';
// \1 反向引用確保首尾引號一致(或同為無引號)
$pattern = '/<img[^>]*src=(?!(?:["\']?)data:)["\']?([^"\'\s>]+\.(?:gif|jpg|jpeg|png|bmp|webp))["\']?[^>]*>/i';
// 負向前瞻 (?!data:) 排除 data:image/...
$base = "https://example.com/article/";
$html = preg_replace_callback($pattern, function($m) use ($base) {
$url = $m[1];
if (strpos($url, '//') === 0) $url = 'https:' . $url; // 協議相對
elseif ($url[0] !== '/' && strpos($url, '://') === false) $url = $base . $url; // 相對路徑
return '<img src="' . $url . '"' . substr($m[0], strpos($m[0], '"', 5)) . '>';
}, $html);
正則處理 HTML 存在「標籤巢狀、屬性順序不固定、註釋干擾」等缺陷。對於複雜頁面,推薦:
$dom = new DOMDocument();
@$dom->loadHTML('<?xml encoding="utf-8"?>' . $html); // 抑制錯誤
$xpath = new DOMXPath($dom);
$imgs = $xpath->query('//img/@src');
foreach ($imgs as $src) {
$url = $src->nodeValue;
if (preg_match('/\.(gif|jpg|jpeg|png|bmp|webp)$/i', $url)) {
$result[] = $url;
}
}
DOM 解析雖慢約 2-3 倍,但準確率接近 100%,維護成本極低。
[^>]* 而非 .* 限制在單標籤內。["\'] 兼容兩種。i 標誌或字符組 [jJ][pP][gG]。image.jpg?v=1 會被 \.jpg 截斷,需擴展模式 \.(?:gif|jpg|jpeg|png|bmp|webp)(?:\?[^"\'\s>]*)?。簡單場景下,preg_match_all 配合嚴謹正則足以應付;複雜或長期維護項目,請毫不猶豫選擇 DOMDocument + XPath。本文提供的模式已覆蓋 95% 以上實際 HTML,可直接納入工具庫。