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

preg_match_all 全域正則匹配函數詳解

     編輯:PHP 相關知識

函數簡介

preg_match_all 是 PHP 中執行全域正則表達式匹配的核心函數。它會在目標字符串中搜尋所有符合模式的內容,並按指定順序將結果存入數組。與 preg_match 只匹配第一次不同,它能一次性獲取所有匹配項。

語法

int preg_match_all ( string $pattern, string $subject, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]] )
  • pattern:正則表達式模式(需包含分隔符,如 /.../ 或 |...|)。
  • subject:輸入字符串。
  • matches:引用參數,用於接收匹配結果的多維數組。
  • flags:結果排序標記,常用 PREG_PATTERN_ORDER(默認)與 PREG_SET_ORDER。
  • offset:開始搜尋的偏移量。

返回整個模式匹配的次數(可能為零),出錯返回 FALSE。

關鍵標記:PREG_PATTERN_ORDER vs PREG_SET_ORDER

1. PREG_PATTERN_ORDER(默認)

結果按「模式分組」排序:

  • $matches[0]:完整模式匹配的所有字符串組成的數組。
  • $matches[1]:第一個捕獲組匹配的所有字符串組成的數組。
  • $matches[2]:第二個捕獲組... 以此類推。

示例:

<?php
$subject = "<b>example: </b><div align=left>this is a test</div>";
preg_match_all("|<[^>]+>(.*)</[^>]+>|U", $subject, $out, PREG_PATTERN_ORDER);

print_r($out[0]); // 完整標簽匹配
// Array ( [0] => <b>example: </b> [1] => <div align=left>this is a test</div> )

print_r($out[1]); // 第一個捕獲組(標簽內容)
// Array ( [0] => example: [1] => this is a test )

2. PREG_SET_ORDER

結果按「匹配項分組」排序:

  • $matches[0]:第一組匹配的所有內容(完整匹配、捕獲組1、捕獲組2...)。
  • $matches[1]:第二組匹配的所有內容...

示例:

<?php
preg_match_all("|<[^>]+>(.*)</[^>]+>|U", $subject, $out, PREG_SET_ORDER);

print_r($out[0]);
// Array ( [0] => <b>example: </b> [1] => example: )

print_r($out[1]);
// Array ( [0] => <div align=left>this is a test</div> [1] => this is a test )

3. PREG_OFFSET_CAPTURE

若設置此標記,返回數組的每個單元將變為 [matched_string, offset] 形式,即同時返回匹配字符串及其在 subject 中的偏移量。PHP 4.3.0+ 可用。

實戰範例

範例 1:提取所有電話號碼

<?php
$text = "Call 555-1212 or 1-800-555-1212";
preg_match_all("/\(?(\d{3})?\)?[-.\s]?\d{3}[-.\s]\d{4}/x", $text, $phones);
print_r($phones[0]);

範例 2:匹配 HTML 標簽(貪婪與非貪婪)

<?php
$html = "<b>bold text</b><a href=howdy.html>click me</a>";
// 使用反向引用 \2 匹配同名閉合標簽
preg_match_all("/(<(\w+)[^>]*>)(.*)(<\/\\2>)/", $html, $matches);

for ($i = 0; $i < count($matches[0]); $i++) {
    echo "matched: " . $matches[0][$i] . "\n";
    echo "part 1 (open tag): " . $matches[1][$i] . "\n";
    echo "part 2 (tag name): " . $matches[2][$i] . "\n";
    echo "part 3 (content): " . $matches[3][$i] . "\n";
    echo "part 4 (close tag): " . $matches[4][$i] . "\n\n";
}

輸出:

matched: <b>bold text</b>
part 1: <b>
part 2: bold text
part 3: </b>

matched: <a href=howdy.html>click me</a>
part 1: <a href=howdy.html>
part 2: click me
part 3: </a>

常見陷阱與技巧

  • 貪婪模式:默認 .* 會匹配盡可能多字符,導致跨標簽匹配。使用 U 修飾符(非貪婪)或 .*? 解決。
  • 雙引號轉義:在雙引號字符串中,反斜線需雙寫(如 \\2 代表反向引用)。
  • 性能:對超大文本,考慮分塊處理或使用 offset 參數避免記憶體耗盡。

總結

preg_match_all 是文本解析、數據提取的利器。掌握 PREG_PATTERN_ORDER 與 PREG_SET_ORDER 的區別,能讓你根據業務需求靈活選擇數據結構,編寫更清晰的解析邏輯。

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