從富文本編輯器儲存的 HTML 中提取、修改圖片屬性(src、width、height、class 等)是常見需求。本文提供健壯的正則模式與實用範例。
<?php
$html = '<p>內文</p> <img src="photo.jpg" width="300" height="200" alt="風景" class="img-responsive"> <div>其他</div>';
// 1. 取得完整 img 標籤
preg_match('/<img\b[^>]*>/i', $html, $m);
echo $m[0]; // 完整 img 標籤
// 2. 提取指定屬性值
function getImgAttr(string $html, string $attr): ?string
{
$pattern = '/<img\b[^>]*\b' . preg_quote($attr, '/') . '\s*=\s*(["\'])(.*?)\1/i';
return preg_match($pattern, $html, $m) ? $m[2] : null;
}
echo getImgAttr($html, 'src'); // photo.jpg
echo getImgAttr($html, 'width'); // 300
echo getImgAttr($html, 'class'); // img-responsive
// 3. 批次提取所有圖片的 src
preg_match_all('/<img\b[^>]*\bsrc\s*=\s*(["\'])(.*?)\1/i', $html, $m);
print_r($m[2]); // 所有 src 陣列
$html = '<img src="/uploads/photo.jpg" width="800" height="600">';
// 替換 src:/uploads/ → /uploads/thumbs/
$newHtml = preg_replace(
'/(<img\b[^>]*\bsrc\s*=\s*["\'])([^"\']*)(["\'])/i',
'$1/uploads/thumbs/$2$3',
$html
);
// 結果:
| 問題 | 說明 |
|---|---|
| 巢狀標籤 | 正則無法正確處理 ` |
| 屬性順序/換行 | 需寫複雜模式匹配單引號、雙引號、無引號、跨行 |
| 編碼實體 | `"`、`<` 會干擾匹配 |
| 效能 | 大量 HTML 正則回溯慢 |
<?php
function processImages(string $html, callable $callback): string
{
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML('' . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_clear_errors();
foreach ($dom->getElementsByTagName('img') as $img) {
$callback($img); // 回調中操作 $img->setAttribute()、$img->removeAttribute()
}
return $dom->saveHTML();
}
// 使用範例:轉換為響應式圖片
$html = processImages($html, function (DOMElement $img) {
$src = $img->getAttribute('src');
if (str_starts_with($src, '/uploads/')) {
$img->setAttribute('src', '/uploads/thumbs/' . basename($src));
}
$img->removeAttribute('width');
$img->removeAttribute('height');
$img->setAttribute('class', 'img-fluid');
$img->setAttribute('loading', 'lazy');
});
src 為佔位圖 → 以 `data-src` 為準