首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 正則提取圖片網址完整指南:從 HTML 解析到相對/絕對路徑處理

     編輯:PHP 相關知識

前言

爬蟲、內容遷移、編輯器圖片上傳等場景常需從 HTML 中提取 <img> 的 src 屬性。本文系統整理正則寫法演進、零寬斷言限制、相對路徑轉絕對、無副檔名圖片處理等實戰技巧。

基礎正則演進

需求正則說明
最簡單/src=["']([^"']+)["']/i匹配所有 src,含 JS/CSS/iframe,誤判率高
限定 img 標籤/<img[^>]+src=["']([^"']+)["']/i較精確,但屬性順序不固定可能漏匹
容忍屬性順序/<img\b[^>]*\bsrc=["']([^"']+)["']/i推薦通用寫法,\b 確保單字邊界
提取 src 並保留標籤上下文/<img(\s[^>]*)?src=["']([^"']+)["']/i捕獲組 2 為網址,組 1 為其他屬性

PHP 實作:preg_match_all 批次提取

function extractImageUrls(string $html): array {
    $pattern = '/<img\b[^>]*\bsrc=["\']([^"\']+)["\']/i';
    preg_match_all($pattern, $html, $matches);
    return $matches[1] ?? []; // 捕獲組 1 為網址
}

$html = '<img src="photo.jpg" alt="test"> <img data-src="lazy.png" src="real.png">';
print_r(extractImageUrls($html));
// Array ( [0] => photo.jpg [1] => real.png )

進階挑戰與解決方案

1. 相對路徑轉絕對路徑

function toAbsoluteUrls(array $urls, string $baseUrl): array {
    $base = rtrim($baseUrl, '/') . '/';
    return array_map(function($url) use ($base) {
        if (preg_match('/^https?:\/\//i', $url)) return $url; // 已是絕對
        if (str_starts_with($url, '//')) return 'https:' . $url; // 協議相對
        if (str_starts_with($url, '/')) {
            $parsed = parse_url($base);
            return $parsed['scheme'] . '://' . $parsed['host'] . $url; // 根相對
        }
        return $base . $url; // 同目錄相對
    }, $urls);
}

2. 無副檔名圖片 (如 CDN 動態圖片)

正則不可依賴副檔名過濾。直接提取 src 值,後續用 getimagesize() 或 HTTP HEAD 檢查 Content-Type: image/... 驗證。

3. 零寬斷言 (?<=...) 在 PHP 的限制

PHP PCRE 要求 lookbehind 固定長度,故 (?<=img.+?src=") 會報錯。解決:改用捕獲組 (src=["']([^"']+)["']) 取組 2,或用 \K 重設匹配起點:/<img\b[^>]*\bsrc=["']\K[^"']+/i。

4. 處理單引號/雙引號/無引號 (不合規但實際存在)

$pattern = '/<img\b[^>]*\bsrc=(["\']?)([^"\'>\s]+)\1/i';
// \1 反向引用確保首尾引號一致,組 2 為網址

完整工具類建議

class ImageExtractor {
    public static function extract(string $html, string $baseUrl = ''): array {
        $urls = [];
        preg_match_all('/<img\b[^>]*\bsrc=(["\']?)([^"\'>\s]+)\1/i', $html, $m);
        $urls = $m[2] ?? [];
        if ($baseUrl) $urls = self::toAbsolute($urls, $baseUrl);
        return array_values(array_unique($urls));
    }
    private static function toAbsolute(array $urls, string $base): array { ... }
}

總結

核心正則 /<img\b[^>]*\bsrc=(["\']?)([^"\'>\s]+)\1/i 兼容引號、屬性順序、無引號情況。提取後務必轉絕對路徑並驗證 Content-Type。避免用零寬斷言、副檔名過濾等脆弱寫法。大規模爬蟲建議改用 DOMDocument 或 symfony/dom-crawler 解析器,健壯度遠超正則。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved