tags($filename, $tag) 函數用於從 HTML 文件中提取指定標籤的完整資訊,返回結構化陣列,包含標籤名、標籤內文本、以及所有屬性鍵值對。適用於 HTML 內容分析、鏈接提取、圖片資源掃描、表單欄位解析等場景。
$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") 將文件切分為以目標標籤開頭的片段。
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); // 初步按空格分割屬性
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" 此類屬性值包含空格導致錯誤分割的問題,通過檢測引號配對狀態將分散的片段重新合併。
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
)
)
)
eregi* 系列 → preg_match/preg_replace (PCRE)split() → explode() 或 preg_split()sql_regcase() → 正則模式修飾符 ifunction 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;
}
優勢:原生支援巢狀結構、實體解碼、編碼自動處理、容錯性強、效能更佳。
a.external、img[src$=.png])<a> 標籤 HREF 屬性,批次驗證死鏈<img> 的 SRC、ALT、尺寸資訊,生成圖庫索引<form>、<input>、<select> 結構,自動生成 API 文檔<meta>、<title>、<h1> 等關鍵標籤完整性該函數展示了早期 PHP 以正則表達式解析 HTML 的經典思路,雖然在處理複雜巢狀、異常標籤、編碼問題上有局限,但其屬性值空格處理邏輯值得借鑑。現代開發強烈建議遷移至 DOMDocument 或 Masterminds/HTML5-Parser 等專業解析庫,獲得更健壯、標準合規的解析能力。