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

PHP 正則表達式完全指南:PCRE 函數詳解與實戰技巧

     編輯:PHP 相關知識

前言:正則,愛恨交織的利器

正則表達式是文本處理的瑞士軍刀,強大卻晦澀。PHP 提供兩套正則引擎:PCRE (Perl Compatible Regular Expressions) 與已棄用的 POSIX (ereg_*)。自 PHP 5.3 起 POSIX 正式棄用,PHP 7/8 已完全移除。本文聚焦 PCRE,系統梳理核心概念、常用元字符、修飾符、分組引用,並附贈高頻實戰片段,助你從「正則小白」進階為「模式匹配達人」。

PCRE 基礎語法速查

定界符與修飾符

PCRE 模式必須被一對定界符包裹,常用 /.../、#...#、~...~。修飾符緊隨結尾定界符之後:

修飾符名稱作用典型場景
iPCRE_CASELESS大小寫不敏感關鍵詞搜索、用戶輸入校驗
mPCRE_MULTILINE^/$ 匹配每行首尾多行文本逐行解析
sPCRE_DOTALL. 匹配換行符跨標簽提取 HTML 內容
xPCRE_EXTENDED忽略模式中的空白與註釋編寫可讀性強的複雜正則
uPCRE_UTF8按 UTF-8 碼點匹配中文/多語言匹配必加
UPCRE_UNGREEDY反轉貪婪/非貪婪模式配合 ? 精確控制匹配長度
ePREG_REPLACE_EVAL已移除 (PHP 7+)請改用 preg_replace_callback()

核心元字符速查表

元字符含義等價類示例
\A字符串絕對開頭-/\Aphp/ 僅匹配開頭
\Z字符串絕對結尾(含末尾換行)-/php\Z/
\z字符串絕對結尾(不含換行)-更嚴格的結尾錨點
\b單詞邊界-/\bcat\b/ 匹配單詞 cat
\B非單詞邊界-/\Bcat\B/ 匹配 scatter 中的 cat
\d數字[0-9]/\d{3}-\d{8}/ 電話號
\D非數字[^0-9]-
\w單詞字符(字母/數字/下劃線)[a-zA-Z0-9_]變量名校驗
\W非單詞字符[^a-zA-Z0-9_]-
\s空白字符[\f\n\r\t\v]/\s+/ 匹配多空白
\S非空白字符[^\f\n\r\t\v]-
.任意字符(除換行,s 修飾符下含換行)-/a.b/ 匹配 axb, ab

量詞與貪婪/非貪婪模式

量詞含義貪婪(默認)非貪婪(加?)
*0 次或多次.* 匹配盡可能多.*? 匹配盡可能少
+1 次或多次.+.+?
?0 次或 1 次.?.??
{n}恰好 n 次\d{3}-
{n,}至少 n 次\d{2,}\d{2,}?
{n,m}n 到 m 次\d{3,5}\d{3,5}?

分組、捕獲與反向引用

捕獲組 vs 非捕獲組

$pattern = '/(\d{4})-(\d{2})-(\d{2})/';          // 捕獲組:$1=年, $2=月, $3=日
$pattern = '/(?:\d{4})-(\d{2})-(\d{2})/';        // (?:...) 非捕獲組:$1=月, $2=日
$pattern = '/(?\d{4})-(?\d{2})/';   // 命名捕獲組 (PHP 5.2.2+): $matches['year']

反向引用:\1, \2, \k<name>

/'; // 命名引用

PCRE 核心函數族詳解

函數用途返回值關鍵參數
preg_match()執行單次匹配int (0/1/false),$matches 存捕獲結果$pattern, $subject, &$matches, $flags, $offset
preg_match_all()全局匹配所有int 匹配次數,$matches 結構由 PREG_PATTERN_ORDER/PREG_SET_ORDER 控制同上
preg_replace()正則替換替換後字符串/數組$pattern, $replacement, $subject, $limit, &$count
preg_replace_callback()回調替換(推薦替代 /e)替換後字符串callable $callback 接收 $matches
preg_split()正則分割字符串數組$pattern, $subject, $limit, $flags
preg_grep()正則過濾數組元素匹配的元素數組$pattern, $input, $flags
preg_quote()轉義正則特殊字符轉義後字符串$str, $delimiter = null
preg_last_error()獲取最後錯誤碼int (PREG_NO_ERROR 等)調試必備

高頻實戰片段庫

1. 提取 HTML 標簽屬性值 (action/src/href)

$html = '<form action="/login" method="post"><img src="logo.png">';
preg_match_all('/\s(action|src|href)\s*=\s*["\']([^"\']+)["\']/i', $html, $m);
// $m[2] = ['/login', 'logo.png']

2. 回調函數動態重寫鏈接 (補全域名)

3. 斷言提取無屬性標簽內容

bold 這類無屬性標簽的內容
$str = '<b>bold</b> <span class="x">no</span>';
preg_match_all('/(?<=<(\w+)>).*?(?=<\/\1>)/s', $str, $m);
// $m[0] = ['bold']

4. 驗證身份證號 (簡化版,含校驗碼邏輯需額外實現)

5. 匹配中文/多語言 (必加 u 修飾符)

性能優化與避坑指南

  1. 能用 strpos/explode/str_replace 解決的,絕不用正則 — 字符串函數快 10-100 倍。
  2. 避免災難性回溯:(a+)+ 匹配 aaaaaaaaaaaa! 會指數級爆炸。使用 ++ 佔有優先量詞或原子組 (?>...) 斷路。
  3. 預編譯緩存:長期運行進程 (Swoole/RoadRunner) 中,將模式存入靜態變量,避免重複編譯。
  4. 大數據分塊處理:preg_match_all 返回巨大數組會撐爆內存,改用 preg_split + 生成器流式處理。
  5. JIT 加速 (PHP 8+):開啟 pcre.jit=1 (默認開啟),複雜正則可獲 2-5 倍提速。

結語

正則表達式是把雙刃劍:用得好是「一行代碼解決萬行邏輯」,用不好是「寫時只懂我與天,改時只懂天」。掌握 PCRE 核心語法、善用修飾符與斷言、養成「先想字符串函數能不能搞定」的習慣,才能真正駕馭這把利器。建議收藏本文速查表,實戰中多練 preg_replace_callback 與 u 修飾符,處理多語言文本將不再是噩夢。

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