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

PHP HTML 標籤解析器:從文件提取標籤屬性與內容的實用函數

     編輯:PHP 綜合知識

函數功能與定位

tags($filename, $tag) 函數用於從 HTML 文件中提取指定標籤的完整資訊,返回結構化陣列,包含標籤名、標籤內文本、以及所有屬性鍵值對。適用於 HTML 內容分析、鏈接提取、圖片資源掃描、表單欄位解析等場景。

代碼實現深度解析

1. 文件讀取與預處理

$buffer = join("", file($filename));      // 讀取整文件為字串
$buffer = eregi_replace("\r\n", "", $buffer); // 移除換行符
$tagkey = sql_regcase($tag);                // 生成大小寫不敏感匹配模式
$buffer = eregi_replace("<$tagkey ", "\n<$tag ", $buffer); // 標籤前換行便於分割
$ar = split("\n", $buffer);                 // 按行分割

關鍵技巧:sql_regcase() 將標籤名轉為類似 [aA] 的模式,配合 eregi_replace 實現大小寫不敏感匹配;在每個目標標籤前插入換行符,利用 split("\n") 將文件切分為以目標標籤開頭的片段。

2. 逐行解析主迴圈

foreach ($ar as $v) {
    if (!eregi("<$tagkey ", $v)) continue; // 跳過非目標標籤行
    
    // 正則提取:標籤屬性部分、可選的內容與閉合標籤
    eregi("<$tagkey ([^>]*)((.*)</$tagkey)?", $v, $regs);
    
    $p['tagName'] = strtoupper($tag);
    if ($regs[3]) $p['Text'] = $regs[3]; // 內容文本
    
    // 屬性字串清理:多空格合併、等號周圍空格移除
    $s = trim(eregi_replace("[ \t]+", " ", $regs[1])) . " ";
    $s = eregi_replace(" *= *", "=", $s);
    $a = split(" ", $s); // 初步按空格分割屬性

3. 屬性值包含空格的處理(核心邏輯)

for ($i = 0; $i < count($a); $i++) {
    $ch = array();
    if (eregi('=["\']', $a[$i])) { // 屬性值以引號開頭
        $j = $i + 1;
        while (!eregi('["\']$', $a[$i])) { // 直到找到結尾引號
            $a[$i] .= " " . $a[$j];
            unset($a[$j]); // 合併被空格分割的屬性值片段
        }
    }
}

這段邏輯解決了 alt="hello world" 此類屬性值包含空格導致錯誤分割的問題,通過檢測引號配對狀態將分散的片段重新合併。

4. 屬性鍵值對最終解析

foreach ($a as $k) {
    $name = strtoupper(strtok($k, "=")); // 屬性名轉大寫
    $value = strtok("\0");               // 獲取等號後內容
    if (eregi('^["\']', $value))         // 移除首尾引號
        $value = substr($value, 1, -1);
    if ($name)
        $p['Attrs'][$name] = $value;
}
$pp[] = $p;

使用 strtok 分割鍵值,移除引號包裹,構建關聯陣列 Attrs。

返回值結構示例

Array
(
    [0] => Array
        (
            [tagName] => A
            [Text] => 點擊這裡
            [Attrs] => Array
                (
                    [HREF] => /page.php
                    [CLASS] => btn
                    [TARGET] => _blank
                )
        )
    [1] => Array
        (
            [tagName] => IMG
            [Text] => 
            [Attrs] => Array
                (
                    [SRC] => /logo.png
                    [ALT] => 網站Logo
                    [WIDTH] => 120
                )
        )
)

現代化改進建議

1. 替代棄用函數

  • eregi* 系列 → preg_match/preg_replace (PCRE)
  • split() → explode() 或 preg_split()
  • sql_regcase() → 正則模式修飾符 i

2. 使用 DOMDocument 重構(推薦)

function tags_modern($filename, $tag) {
    $dom = new DOMDocument();
    @$dom->loadHTMLFile($filename); // 抑制非標準HTML警告
    $elements = $dom->getElementsByTagName($tag);
    $result = [];
    foreach ($elements as $el) {
        $attrs = [];
        foreach ($el->attributes as $attr) {
            $attrs[strtoupper($attr->name)] = $attr->value;
        }
        $result[] = [
            'tagName' => strtoupper($tag),
            'Text' => trim($el->textContent),
            'Attrs' => $attrs
        ];
    }
    return $result;
}

優勢:原生支援巢狀結構、實體解碼、編碼自動處理、容錯性強、效能更佳。

3. 功能擴展方向

  • 支援 CSS 選擇器語法(如 a.external、img[src$=.png])
  • 新增 XPath 查詢介面
  • 提供流式解析介面處理大文件
  • 輸出標準化 JSON 格式便於前端消費

應用場景實例

  • 鏈接檢測工具:提取所有 <a> 標籤 HREF 屬性,批次驗證死鏈
  • 圖片資源收集:解析 <img> 的 SRC、ALT、尺寸資訊,生成圖庫索引
  • 表單結構分析:提取 <form>、<input>、<select> 結構,自動生成 API 文檔
  • SEO 審計:檢查 <meta>、<title>、<h1> 等關鍵標籤完整性

總結

該函數展示了早期 PHP 以正則表達式解析 HTML 的經典思路,雖然在處理複雜巢狀、異常標籤、編碼問題上有局限,但其屬性值空格處理邏輯值得借鑑。現代開發強烈建議遷移至 DOMDocument 或 Masterminds/HTML5-Parser 等專業解析庫,獲得更健壯、標準合規的解析能力。

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