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

PHP preg_match_all 正則實戰:從 HTML 解析到資料提取的完整範例

     編輯:PHP 相關知識

preg_match_all 是 PHP 批次匹配正則表達式的核心函數,能一次性提取所有符合模式的子串並保留捕獲組。本文以「解析多個 DIV 區塊的 ID 與內容」為主線,逐步拆解正則構建思路、陣列結構、常見陷阱與最佳實踐。

目標 HTML 片段

$html = '<div id="biuuu">php100</div><div id="biuuu_2">php1002</div><div id="biuuu_3">php1003</div>';

需提取:biuuu、biuuu_2、biuuu_3 與對應內容 php100、php1002、php1003。

正則構建步驟

  1. 定位單個區塊:<div id="([^"]+)">([^<]+)</div>
  2. 解釋:
    • ([^"]+):捕獲組 1,匹配非雙引號字元 (ID)
    • ([^<]+):捕獲組 2,匹配非 < 字元 (內容),避免貪婪吞噬後續標籤
  3. 完整模式:/<div id="([^"]+)">([^<]+)<\/div>/

代碼實作

<?php
$html = '<div id="biuuu">php100</div><div id="biuuu_2">php1002</div><div id="biuuu_3">php1003</div>';

$pattern = '/<div id="([^"]+)">([^<]+)<\/div>/';
preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);

echo "完整匹配陣列結構 (PREG_SET_ORDER):\n";
print_r($matches);

/* 輸出:
Array
(
    [0] => Array
        (
            [0] => <div id="biuuu">php100</div>   // 整段匹配
            [1] => biuuu                            // 捕獲組 1
            [2] => php100                           // 捕獲組 2
        )
    [1] => Array
        (
            [0] => <div id="biuuu_2">php1002</div>
            [1] => biuuu_2
            [2] => php1002
        )
    [2] => Array
        (
            [0] => <div id="biuuu_3">php1003</div>
            [1] => biuuu_3
            [2] => php1003
        )
)
*/

// 業務處理
foreach ($matches as $m) {
    echo "ID: {$m[1]}, Content: {$m[2]}\n";
}

PREG_SET_ORDER vs PREG_PATTERN_ORDER

旗標陣列結構適用場景
PREG_SET_ORDER (推薦) $matches[0] = [全匹配, 組1, 組2...] 逐筆處理,語義清晰
PREG_PATTERN_ORDER (預設) $matches[0] = [全匹配陣列], $matches[1] = [組1陣列]... 需分別操作各捕獲組陣列時

常見陷阱與對策

陷阱原因對策
貪婪匹配吞噬多個標籤.* 或 .+ 匹配盡可能多字元使用非貪婪 .*? 或排除字元類 [^<]+
跨行匹配失效點號 . 預設不匹配換行加 s 修飾符 /pattern/s 或用 [\s\S]*?
特殊字元未轉義/、.、*、?、(、) 等使用 preg_quote() 或手動加反斜線
編碼不一致字串為 UTF-8 但模式無 u 修飾符加 u 修飾符 /pattern/u,確保字元邊界正確
災難性回溯巢狀量詞 (a+)+ 遇長字串避免巢狀量詞,改用確定性模式或具體字元類

進階:提取屬性順序不固定的標籤

$html = '<div class="box" id="A">...</div><div id="B" class="box">...</div>';
// 使用前瞻/後瞻或多模式
$pattern = '/<div\b(?=[^>]*\bid="([^"]+)")[^>]*>([^<]+)<\/div>/';
// 解釋:(?=...) 正向前瞻確保 id 存在並捕獲,不消耗字元

最佳實踐清單

  1. 優先使用 DOMDocument + DOMXPath 解析 HTML/XML,正則僅用於非結構化文本或極簡片段。
  2. 模式加 u 修飾符支援 Unicode。
  3. 使用 PREG_SET_ORDER 並配合 foreach 處理。
  4. 複雜模式拆分為多個簡單模式逐步過濾。
  5. 單元測試覆蓋正則邊界案例 (空內容、特殊字元、巢狀標籤)。

正則表達式是雙刃劍:威力強大但易寫成「寫時讀不懂」的代碼。掌握 preg_match_all 陣列結構、貪婪/非貪婪、修飾符、常見陷阱,並建立「能用 DOM 解析就不用正則」的原則,才能在資料提取任務中游刃有餘。

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