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

PHP 使用正則表達式提取、修改 img 標籤屬性的完整指南

     編輯:PHP 綜合知識

前言

在 CMS 系統、富文本編輯器內容處理、數據遷移等場景中,常需從 HTML 字符串中提取或修改 `` 標籤的屬性(如 `src`、`width`、`height`、`style` 等)。本文系統梳理基於 PCRE 正則表達式的處理方案,並針對常見陷阱提供最佳實踐。

一、核心正則模式詳解

1. 匹配完整的 img 標籤

$pattern = '/<img\s+[^>]*?src\s*=\s*([\'"])(.*?)\\1[^>]*?\/?\s*>/i';
  • `\s+`:匹配標籤名後的至少一個空白字符
  • [^>]*?`:非貪婪匹配非 `>` 字符(屬性區)
  • `src\s*=\s*`:匹配 src 屬性名與等號,允許空白
  • `([\'"])`:捕獲引號類型(單雙引號兼容)
  • `(.*?)`:非貪婪捕獲 URL 值
  • `\\1`:反向引用第一個捕獲組(確保引號成對)
  • `\/?\s*>`:匹配可選的自閉合斜杠與結束符

2. 提取指定屬性值(以 src 為例)

$pattern = '/<img[^>]*?src\s*=\s*([\'"])(.*?)\\1/i';

使用 `preg_match()` 時,`$matches[2]` 即為 URL 值。

3. 提取 width/height 等無引號屬性

$pattern = '/<img[^>]*?width\s*=\s*([\'"]?)(\d+)\\1/i';

支持有引號、無引號兩種寫法,`$matches[2]` 為數值。

二、實戰代碼示例

場景 1:從混合 HTML 中提取所有圖片信息

<?php
$html = '<p>內容</p> <img src="a.jpg" width="100"> <div>其他</div> <img src=\'b.png\' height=50>';

$pattern = '/<img\s+([^>]*?src\s*=\s*([\'"])(.*?)\\2[^>]*?)\/?\s*>/is';
preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);

foreach ($matches as $m) {
    $fullTag = $m[0];
    $src = $m[3];
    // 進一步解析其他屬性...
    echo "標籤: $fullTag\n圖片: $src\n---\n";
}
?>

場景 2:將圖片路徑批量替換為縮略圖路徑

需求:將 `src="upload/images/xxx.jpg"` 改為 `src="upload/_thumbs/images/xxx.jpg"`,並移除 `width`/`height` 屬性(避免縮略圖變形)。

<?php
$html = '<img src="upload/images/a.jpg" width="200" height="150">
<img src="upload/images/b.png" style="float:left">';

// 方案 A:分步處理(推薦,可讀性強)
// 1. 替換 src 路徑
$html = preg_replace_callback(
    '/(<img[^>]*?src\s*=\s*([\'"]))(.*?)\\2/i',
    function ($m) {
        $prefix = $m[1];
        $quote = $m[2];
        $url = $m[3];
        // 路徑轉換邏輯
        $newUrl = preg_replace('/(upload\/)images\//', '$1_thumbs/images/', $url);
        return $prefix . $newUrl . $quote;
    },
    $html
);

// 2. 移除 width/height 屬性
$html = preg_replace('/\s(width|height)\s*=\s*([\'"]?)\d+\\2/i', '', $html);

echo $html;
// 輸出:
// <img src="upload/_thumbs/images/a.jpg">
// <img src="upload/_thumbs/images/b.png" style="float:left">
?>

場景 3:統一補全 alt 屬性(SEO 優化)

<?php
$html = preg_replace_callback(
    '/(<img[^>]*?)(?:\salt\s*=\s*([\'"])(.*?)\\2)?([^>]*>)/i',
    function ($m) {
        // 若已有 alt 則保持,否則添加默認值
        $alt = $m[3] ?? '圖片說明';
        return $m[1] . ' alt="' . htmlspecialchars($alt) . '"' . $m[4];
    },
    $html
);
?>

三、常見陷阱與最佳實踐

  1. 不要用正則解析完整 HTML 文檔:正則無法正確處理嵌套標籤、註釋、CDATA 等複雜結構。僅適用於提取/修改已知格式的片段。
  2. 優先使用 DOMDocument:對於結構化操作(如遍歷所有圖片、修改屬性、輸出合法 HTML),PHP 內置 `DOMDocument` 更健壯:
    $dom = new DOMDocument();
    $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    foreach ($dom->getElementsByTagName('img') as $img) {
        $src = $img->getAttribute('src');
        $img->setAttribute('src', convertToThumb($src));
        $img->removeAttribute('width');
        $img->removeAttribute('height');
    }
    $newHtml = $dom->saveHTML();
    
  3. 正則修飾符選擇:
    • `i`:大小寫不敏感(HTML 標籤/屬性不區分大小寫)
    • `s`:單行模式,讓 `.` 匹配換行符(屬性值可能跨行)
    • `u`:UTF-8 模式(處理中文屬性值時必須)
  4. 防止災難性回溯:避免在 `[^>]*` 等模式中嵌套量詞,優先使用具體字符類或原子組。
  5. 編碼一致性:確保正則模式、輸入字符串、PHP 文件編碼均為 UTF-8,並使用 `u` 修飾符。

四、性能對比建議

場景推薦方案理由
提取單頁少量圖片信息正則 `preg_match_all`代碼簡潔、無依賴、速度快
批量修改屬性、需輸出合法 HTMLDOMDocument自動處理實體編碼、標籤閉合、嵌套結構
超大 HTML 文檔(>1MB)流式解析器 (XMLReader)內存佔用恆定、不會載入整個文檔

五、總結

正則表達式在處理 `` 標籤屬性提取與簡單替換時極為高效,但需嚴格控制適用邊界。核心原則:只處理扁平化、結構可預期的 HTML 片段。涉及結構變更、實體編碼、嵌套標籤時,請毫不猶豫選擇 `DOMDocument`。兩者結合,可構建健壯的富文本圖片處理流程。

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