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

PHP 正則過濾 HTML 標籤屬性實戰:保留指定屬性、移除危險屬性、完整淨化方案

     編輯:PHP 綜合知識

富文本編輯器輸出、第三方內容嵌入、爬蟲資料清洗,常需精準控制 HTML 標籤屬性:保留 src、alt、href 等安全屬性,移除 onclick、style、onload 等 XSS 風險屬性。本文提供正則進階模式、常見場景現成模式、完整淨化管線,並對比 strip_tags()、HTMLPurifier 適用邊界。

核心正則模式庫

1. 保留指定屬性,移除其餘(否定前瞻)

// 保留 src,移除 img 標籤其他所有屬性
$html = preg_replace('/\s(?!src\b)[a-zA-Z-]+=(["\']).*?\1/iu', '', $html);

// 保留 src 和 alt
$html = preg_replace('/\s(?!src\b|alt\b)[a-zA-Z-]+=(["\']).*?\1/iu', '', $html);

// 通用函式:保留 $allow 陣列屬性
function keepAttributes(string $html, array $allow): string
{
    $pattern = '/\s(?!' . implode('|', array_map('preg_quote', $allow)) . '\b)[a-zA-Z-]+=(["\']).*?\1/iu';
    return preg_replace($pattern, '', $html);
}
// 用法:keepAttributes($html, ['src', 'alt', 'title', 'href']);

2. 移除指定危險屬性(事件處理器、style 等)

$dangerous = ['on\w+', 'style', 'action', 'background', 'dynsrc', 'lowsrc'];
$pattern = '/\s(' . implode('|', $dangerous) . ')\s*=\s*(["\']).*?\2/iu';
$html = preg_replace($pattern, '', $html);

3. 移除所有屬性,保留標籤結構

//  → 
$html = preg_replace('/<([a-z]+)\s[^>]*>/i', '<$1>', $html);

4. 完整 HTML 淨化管線(參考原文陣列模式)

function purifyHtml(string $html): string
{
    $search = [
        // 移除 script 及內容
        "']*>.*?'si",
        // 移除 HTML 註解
        "''si",
        // 移除所有標籤屬性(若需保留請用上方 keepAttributes)
        "'<([a-z]+)\s[^>]*>'i",
        // 移除多餘空白
        "'([\r\n])[\s]+'",
        // 實體還原(視需求決定是否保留)
        "'&(quot|#34);'i", "'&(amp|#38);'i",
        "'&(lt|#60);'i",  "'&(gt|#62);'i",
        "'&(nbsp|#160);'i",
    ];
    $replace = [
        '', '', '<$1>', "\\1", '"', '&', '<', '>', ' '
    ];
    return preg_replace($search, $replace, $html);
}

實戰場景範例

場景 A:圖片標籤只保留 src、alt、width、height

$html = '圖';
$clean = keepAttributes($html, ['src', 'alt', 'width', 'height']);
// 結果:圖

場景 B:連結只保留 href、title、target

$html = '連結';
$clean = keepAttributes($html, ['href', 'title', 'target']);
// 結果:連結

場景 C:移除所有內聯事件與 style

$html = '
內容
'; $clean = preg_replace('/\s(on\w+|style)\s*=\s*(["\']).*?\2/iu', '', $html); // 結果:
內容

正則旗標說明

  • i:大小寫不敏感(HTML 屬性不分大小寫)
  • u:UTF-8 模式(正確處理中文屬性值)
  • s:單行模式(. 匹配換行,配合 .*? 跨行匹配內容)

避坑指南與最佳實踐

誤區風險正確做法
用正則解析任意 HTML巢狀、破損、編碼導致漏洞簡單屬性過濾用正則;複雜結構用 DOMDocument + HTMLPurifier
單一正則處理所有標籤難以維護、效能差分標籤類型處理,或用白名單機制
忽略雙引號/單引號/無引號屬性值繞過過濾模式支援 (["\']).*?\1 或 [^\s>]+
過濾後未編碼輸出殘留 XSS輸出前 htmlspecialchars() 或模板引擎自動轉義

工具鏈推薦

  1. HTMLPurifier:業界標準、白名單機制、支援 HTML5、CSRF 安全、效能可快取。
  2. DOMDocument + DOMXPath:原生、無依賴、精準操作節點屬性。
  3. masterminds/html5-php:HTML5 解析器,配合選取器移除屬性。
  4. 前端 DOMPurify:雙端同步淨化,防禦深度最大化。

總結

正則過濾 HTML 屬性屬於「輕量級防護」,適用於結構可控、標籤有限、效能敏感的場景(如編輯器儲存前預處理、API 回應快速清洗)。面對非受信任、結構複雜、高風險內容,務必使用 HTMLPurifier 或 DOMDocument 白名單淨化。掌握本文模式庫,能覆蓋 80% 日常屬性控制需求,剩下 20% 交給專業淨化庫。

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