PHP 歷史上同時支援兩套正則引擎:
ereg_* 系列):PHP 5.3 棄用,PHP 7.0 **完全移除**;preg_* 系列):**現代 PHP 唯一標準**,功能更強、效能更高、語法更豐富。結論: 僅學習和使用 PCRE。本文系統梳理 PCRE 核心語法、修飾符、函數族與實戰模式。
$pattern = '/^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/i';
// ^ 定界符(可用 # ~ @ 等非字母數字字符)
// i = 不區分大小寫
| 修飾符 | 名稱 | 作用 |
|---|---|---|
i (PCRE_CASELESS) | 不區分大小寫 | 匹配時忽略大小寫 |
m (PCRE_MULTILINE) | 多行模式 | ^/$ 匹配每行首尾而非整個字串首尾 |
s (PCRE_DOTALL) | 單行模式 | . 可匹配換行符(預設不匹配) |
x (PCRE_EXTENDED) | 擴展模式 | 忽略模式中的空白、允許 # 註釋,便於寫複雜正則 |
u (PCRE_UTF8) | UTF-8 模式 | **處理中文/多位元組必加**,將模式和目標字串視為 UTF-8 |
U (PCRE_UNGREEDY) | 非貪婪模式 | 反轉量詞貪婪性(*? 變貪婪,* 變非貪婪) |
D (PCRE_DOLLAR_ENDONLY) | 僅末尾匹配 | $ 僅匹配字串絕對末尾(配合 m 時) |
J (PCRE_DUPNAMES) | 允許重複子模式名 | (?<name>...)(?<name>...) |
| 類別 | 語法 | 說明 |
|---|---|---|
| 預定義字符類 | \d | 數字 [0-9] |
\D | 非數字 [^0-9] | |
\w | 單詞字符 [a-zA-Z0-9_](含下劃線) | |
\W | 非單詞字符 | |
\s | 空白字符 [\s\t\r\n\f\v] | |
\S | 非空白字符 | |
| 定位符 | ^ | 字串/行開頭(m 修飾符影響) |
$ | 字串/行結尾 | |
\A | 絕對字串開頭(不受 m 影響) | |
\z | 絕對字串結尾(不受 m 影響) | |
| 邊界 | \b | 單詞邊界(\w 與 \W 交接處) |
\B | 非單詞邊界 | |
\G | 上次匹配結束位置(配合 preg_match_all/\G 連續掃描) |
| 貪婪 | 非貪婪 | 佔有優先 | 含義 |
|---|---|---|---|
* | *? | *+ | 0 次或多次 |
+ | +? | ++ | 1 次或多次 |
? | ?? | ?+ | 0 次或 1 次 |
{n} | {n}? | {n}+ | 恰好 n 次 |
{n,} | {n,}? | {n,}+ | 至少 n 次 |
{n,m} | {n,m}? | {n,m}+ | n 到 m 次 |
原則: 能用非貪婪解決回溯效能問題時優先用 ?;極端效能敏感場景考慮佔有優先 +(失敗不回溯)。
(...):捕獲組,佔用編號、可被 \1 / $1 反向引用;(?:...):非捕獲組,僅分組不佔編號,**效能更好、推薦常用**;(?<name>...):命名捕獲組(PHP 5.2+),\k<name> 反向引用、$matches['name'] 獲取;(?>...):原子組(佔有優先分組),匹配後不回溯。| 語法 | 名稱 | 條件 |
|---|---|---|
| 正向頻視 | 後面必須匹配 ... | |
(?!...) | 負向頻視 | 後面不能匹配 ... |
(?<=...) | 正向後視 | 前面必須匹配 ...(固定寬度) |
(?<!...) | 負向後視 | 前面不能匹配 ...(固定寬度) |
| 函數 | 功能 | 返回值 | 典型用例 |
|---|---|---|---|
preg_match($pattern, $subject, &$matches, $flags, $offset) | 執行一次匹配 | 1/0/false,$matches[0] 整體匹配,[1]... 子組 | 驗證格式、提取首個匹配 |
preg_match_all($pattern, $subject, &$matches, $flags, $offset) | 全局匹配所有 | 匹配次數,$matches 結構由 PREG_PATTERN_ORDER/PREG_SET_ORDER 決定 | 提取所有連結、標籤、關鍵詞 |
preg_replace($pattern, $replace, $subject, $limit, &$count) | 替換匹配 | 新字串,$count 替換次數 | 模板渲染、敏感詞過濾、格式化 |
preg_replace_callback($pattern, $callback, $subject, $limit, &$count, $flags) | 回調替換 | 新字串 | 複雜替換邏輯(如計算、查表) |
preg_split($pattern, $subject, $limit, $flags) | 正則分割字串 | 陣列 | 分割複雜分隔符(如多種空白、標點) |
preg_grep($pattern, $array, $flags) | 過濾陣列元素 | 匹配的元素陣列 | 從列表篩選符合模式的項 |
preg_quote($str, $delimiter) | 轉義正則元字符 | 安全字串 | 動態構建模式時防注入 |
preg_last_error() | 獲取上次 PCRE 錯誤碼 | 錯誤常數 | 排錯 PREG_BACKTRACK_LIMIT_ERROR 等 |
| 場景 | 模式(含 u 修飾符) | 說明 |
|---|---|---|
| Email(RFC 5322 簡化版) | /^[\w.+-]+@[\w-]+(?:\.[\w-]+)+$/u | 實戰足夠,嚴格驗證請用 filter_var($email, FILTER_VALIDATE_EMAIL) |
| 手機號(中國大陸) | /^1[3-9]\d{9}$/u | 覆蓋當前所有段 |
| 身份證(18 位) | /^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/u | 含校驗碼算法需額外代碼驗證 |
| URL | /^https?:\/\/[\w.-]+(?:\.[\w.-]+)+(?:[\/\?#][^\s]*)?$/iu | 支援 http/https、域名、路徑、查詢、錨點 |
| IPv4 | /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/u | 精確匹配 0-255 四段 |
| 中文姓名(2-10 字) | /^[\x{4e00}-\x{9fa5}]{2,10}$/u | Unicode 範圍 \x{4e00}-\x{9fa5} 覆蓋 CJK 基本區 |
| 強密碼(8-20 位,含大小寫數字特殊) | /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[~!@#$%^&*]).{8,20}$/u | 四組正向頻視強制包含 |
| 日期 YYYY-MM-DD | /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/u | 格式驗證,邏輯合法性(如 2 月 30 日)需代碼校驗 |
| HTML 標籤(含屬性) | /<([a-z]+)(?:\s+[^>]*)?>.*?<\/\1>/isu | 慎用正則解析 HTML,**推薦 DOMDocument** |
| 去除 HTML 標籤保留文本 | /<[^>]+>/u → 替換為 '' | 簡易 strip_tags 替代 |
u 修飾符:處理任何可能含中文/多位元組的字串,否則 .、\w、量詞按字節匹配導致錯誤;(a+)+、(.*)* 等嵌套量詞在長字串失配時指數級回溯 → 使用原子組 (?>a+)+、佔有優先 a++、或改寫邏輯;ini_set('pcre.backtrack_limit', 1000000); ini_set('pcre.recursion_limit', 100000); 防止超大字串導致崩潰;str_starts_with()/str_ends_with() (PHP 8+)、strpos(),比正則快數量級;preg_quote():防止用戶輸入含元字符導致模式錯誤或注入。| POSIX 函數 | PCRE 替代 | 備註 |
|---|---|---|
ereg() | preg_match() | |
eregi() | preg_match($pattern, $str, $matches, 0, 0) + i 修飾符 | |
ereg_replace() | preg_replace() | |
eregi_replace() | preg_replace() + i | |
split() | preg_split() | |
spliti() | preg_split() + i | |
sql_regcase() | 無直接對應 | 構建不區分大小寫模式,現代直接用 i 修飾符 |
正則表達式是「寫時讀懂、改時頭大」的利器。**掌握 PCRE 核心語法、善用修飾符、熟記高頻模式、敬畏回溯效能**,即可在驗證、提取、替換、分割等場景游刃有餘。記住:能用字串函數解決的,絕不寫正則;必須寫正則時,必加 u、必測效能、必備回滾預案。