在網頁爬蟲、內容解析或富文本編輯器處理中,從 HTML 字串中精準提取 <img> 標籤的 src 屬性是常見需求。本文將介紹如何使用 PHP 正則表達式高效完成此任務,並說明常見陷阱與改進方案。
<?php
header('Content-Type: text/html; charset=utf-8');
$html = '<p><img src="images/11111111.jpg" alt="美女" /></p>';
// 修正後的正則:支援單雙引號、屬性順序不固定、自閉合標籤
$pattern = '/<img\\b[^>]*\\bsrc=(["\'])([^"\']+)\\1[^>]*>/i';
preg_match_all($pattern, $html, $matches);
echo '<pre>';
print_r($matches);
?>
| 片段 | 說明 |
|---|---|
<img\\b | 匹配 <img 開頭,單字邊界避免匹配 <image> |
[^>]* | 匹配任意非 > 字元(屬性區) |
\\bsrc= | 匹配 src= 屬性名 |
(["\']) | 捕獲引號類型(單引號或雙引號)到第 1 組 |
([^"\']+) | 捕獲 URL 內容到第 2 組(非貪婪) |
\\1 | 反向引用第 1 組引號,確保首尾一致 |
[^>]*> | 匹配剩餘屬性至標籤結尾 |
/i | 不區分大小寫 |
Array
(
[0] => Array
(
[0] => <img src="images/11111111.jpg" alt="美女" />
)
[1] => Array
(
[0] => "
)
[2] => Array
(
[0] => images/11111111.jpg
)
)
$matches[0]:完整匹配的標籤$matches[2]:我們真正需要的圖片 URLfunction normalizeImgUrls($html, $baseUrl) {
return preg_replace_callback(
'/<img\\b[^>]*\\bsrc=(["\'])([^"\']+)\\1[^>]*>/i',
function($m) use ($baseUrl) {
$url = $m[2];
if (strpos($url, 'http') !== 0 && $url[0] !== '/') {
$url = rtrim($baseUrl, '/') . '/' . ltrim($url, '/');
}
return '<img src="' . $m[1] . $url . $m[1] . '"' . substr($m[0], strpos($m[0], '"', strpos($m[0], 'src=')) + 1);
},
$html
);
}
正則解析 HTML 存在局限性(巢狀標籤、屬性順序、編碼問題)。PHP 內建 DOMDocument 更穩健:
<?php
$dom = new DOMDocument();
libxml_use_internal_errors(true); // 忽略 HTML5 標籤警告
$dom->loadHTML('<meta charset="utf-8">' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_clear_errors();
$images = $dom->getElementsByTagName('img');
foreach ($images as $img) {
echo $img->getAttribute('src') . PHP_EOL;
}
?>
DOMDocument 或 DOMXPath。filter_var($url, FILTER_VALIDATE_URL))。掌握這些技巧,讓你的圖片抓取邏輯更可靠、維護更輕鬆。