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

PHP PCRE 正則表達式完全指南:函數、修飾符、模式與實戰技巧

     編輯:PHP 入門

PHP PCRE 正則表達式深度解析:從基礎語法到高效能模式匹配

PCRE (Perl Compatible Regular Expressions) 是 PHP 核心擴展,提供強大的模式匹配、搜尋替換、字串分割能力。本文系統性介紹 PCRE 函數族、模式修飾符、常用元字元、進階結構、效能優化與實戰範例。

核心函數族概覽

模式修飾符

函數用途回傳值
preg_match執行單次匹配int (0/1/false),匹配結果存入 $matches
preg_match_all全域匹配所有出現int 匹配次數,結果存入 $matches
preg_replace搜尋替換string/array 替換後字串
preg_replace_callback回呼函數替換string/array
preg_split正則分割字串array 子字串陣列
preg_grep陣列元素過濾array 匹配的元素
preg_quote轉義正則特殊字元string 安全字串
preg_filter過濾並替換array 僅返回匹配並替換的元素
preg_last_error取得最後錯誤代碼int 錯誤常數

常用組合

  • /pattern/iu:Unicode 不敏感匹配(推薦預設)
  • /pattern/isu:多行 + 單行 + Unicode

核心元字元與語法速查

修飾符說明
i大小寫不敏感
m多行模式:^$ 匹配行首行尾
s單行模式:. 匹配換行符
x擴展模式:忽略空白、允許註解
uUTF-8 模式:正確處理多位元組字元
U非貪婪模式:量詞預設非貪婪
D$ 僅匹配字串結尾,不匹配結尾換行前
J允許重複命名子組

進階結構:前瞻/後顧斷言

元字元說明
.任意單一字元 (預設不含換行,s 修飾符含換行)
^字串開頭 (m 模式下為行首)
$字串結尾 (m 模式下為行尾)
\d數字 [0-9]
\D非數字
\w單字字元 [a-zA-Z0-9_]
\W非單字字元
\s空白字元 [ \t\r\n\f]
\S非空白字元
\b單字邊界
\B非單字邊界
|或運算
()捕獲群組
(?:)非捕獲群組
(?<name>)命名捕獲群組
*0 次或多次 (貪婪)
+1 次或多次 (貪婪)
?0 次或 1 次
{n,m}n 到 m 次
*? +? ??非貪婪量詞

實戰範例:密碼強度驗證

// 至少 8 字元、含大小寫、數字、特殊符號
$pattern = '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/';
preg_match($pattern, $password);

PREG 常數:preg_match_all 排序模式

語法名稱說明
(?=pattern)正向前瞻後方必須匹配 pattern,不消耗字元
(?!pattern)負向前瞻後方不得匹配 pattern
(?<=pattern)正向後顧前方必須匹配 pattern (固定寬度)
(?<!pattern)負向後顧前方不得匹配 pattern (固定寬度)

preg_split 進階旗標

常數行為結果結構
PREG_PATTERN_ORDER預設,按模式分組$matches[0] 完整匹配,$matches[1] 第一群組...$matches[n] 第 n 群組
PREG_SET_ORDER按匹配集合分組$matches[0] 第一次匹配所有群組,$matches[1] 第二次匹配...
PREG_OFFSET_CAPTURE附加位移資訊每個元素為 [匹配字串, 位移]

範例:保留分隔符分割

preg_split('/(\s+)/', "a  b\tc", -1, PREG_SPLIT_DELIM_CAPTURE);
// ["a", "  ", "b", "\t", "c"]

錯誤處理與除錯

$result = preg_match($pattern, $subject);
if ($result === false) {
    $error = preg_last_error();
    $messages = [
        PREG_INTERNAL_ERROR => 'PCRE 內部錯誤',
        PREG_BACKTRACK_LIMIT_ERROR => '回溯限制超過',
        PREG_RECURSION_LIMIT_ERROR => '遞迴限制超過',
        PREG_BAD_UTF8_ERROR => '無效 UTF-8 序列',
        PREG_BAD_UTF8_OFFSET_ERROR => 'UTF-8 位移無效',
    ];
    throw new Exception($messages[$error] ?? "未知錯誤: $error");
}

效能優化最佳實務

  1. 使用具體字元類別:[a-z] 優於 .
  2. 避免過度回溯:(.*) 在長字串極慢,改用 (.*?) 或 [^"]*
  3. 錨定模式:開頭加 ^、結尾加 $ 減少嘗試位置
  4. 預編譯重用:相同模式重複使用時,PHP 內部快取已編譯模式
  5. 限制匹配次數:preg_match_all($pattern, $subject, $matches, 0, $offset) 指定起始位置
  6. 啟用 JIT:PHP 7.3+ PCRE 編譯時支援 JIT,大幅加速重複執行

實戰範例集

1. Email 驗證 (RFC 5322 簡化版)

$emailPattern = '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/';
if (preg_match($emailPattern, $email)) { /* valid */ }

2. HTML 標籤屬性提取

preg_match_all('/<img\s+[^>]*src\s*=\s*["\']([^"\']+)["\']/i', $html, $matches);
$imageUrls = $matches[1];

3. 千分位格式化數字

preg_replace('/(\d)(?=(\d{3})+(?!\d))/', '$1,', $number);

4. 移除 HTML 標籤保留文字

preg_replace('/<[^>]+>/', '', $html);

PCRE 版本資訊

echo PCRE_VERSION; // 例:10.42 2022-12-11

總結

PCRE 是 PHP 字串處理的核心利器,掌握其函數族、修飾符、進階斷言、效能技巧,能解決 90% 以上的文字解析需求。記住:複雜解析優先考慮專用解析器 (HTML 用 DOMDocument, JSON 用 json_decode),正則用於結構相對固定的模式匹配。

  1. 上一篇文章: No
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
旗標說明
PREG_SPLIT_NO_EMPTY忽略空字串結果
PREG_SPLIT_DELIM_CAPTURE捕獲分隔符 (括號群組)
PREG_SPLIT_OFFSET_CAPTURE結果包含位移