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

PHP 正則表達式函數族完全指南:preg_match、preg_replace、preg_split 實戰詳解

     編輯:PHP 相關知識

前言

PCRE(Perl Compatible Regular Expressions)是 PHP 處理複雜字串模式比對、擷取、替換與分割的核心工具。本文系統整理 preg_match、preg_match_all、preg_replace、preg_split 四大函數的語法、參數、修飾符與實戰範例,並對比同功能的非正則函數效能差異。

核心函數速查表

函數用途回傳值典型場景
preg_match比對一次,找到即停止int (0/1/false),$matches 為參考參數驗證格式、擷取第一組
preg_match_all全域比對所有符合項int 比對次數,$matches 多維陣列擷取所有連結、關鍵字
preg_replace模式替換,支援陣列與回呼string|array 替換後字串樣板引擎、UBB 轉 HTML、敏感詞過濾
preg_split模式分割字串array 分割片段多重分隔符、保留分隔符

preg_match —— 單次比對與擷取

語法

int preg_match ( string $pattern, string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
  • $pattern:PCRE 模式,需包含定界符(如 /.../)
  • $matches[0]:完整比對內容;$matches[1]...:捕獲組
  • PREG_OFFSET_CAPTURE 旗標可同時取得位置索引

範例:驗證手機號碼

<?php
$pattern = '/^1[3-9]\d{9}$/';
$phone = '13800138000';
if (preg_match($pattern, $phone, $m)) {
    echo "有效:{$m[0]}";
} else {
    echo "格式錯誤";
}
?>

preg_match_all —— 全域擷取所有符合項

語法

int preg_match_all ( string $pattern, string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]] )

旗標差異

  • PREG_PATTERN_ORDER(預設):$matches[0] 完整比對陣列,$matches[1] 第一捕獲組陣列...
  • PREG_SET_ORDER:$matches[0] 第一組所有捕獲,$matches[1] 第二組...

範例:擷取文章所有圖片網址

<?php
$html = '<img src="a.jpg"><img src="b.png">';
preg_match_all('/<img\s+src="([^"]+)">/i', $html, $m, PREG_SET_ORDER);
foreach ($m as $set) {
    echo "完整:{$set[0]}\n圖片:{$set[1]}\n";
}
// 輸出兩組完整標籤與圖片網址
?>

preg_replace —— 強大的模式替換引擎

語法

mixed preg_replace ( mixed $pattern, mixed $replacement, mixed $subject [, int $limit = -1 [, int &$count ]] )

進階特性

  1. 陣列模式與替換:$pattern、$replacement 可為陣列,一一對應替換。
  2. e 修飾符(已棄用 PHP 7):將替換字串視為 PHP 程式碼執行,現改用 preg_replace_callback。
  3. 回呼函數:preg_replace_callback($pattern, function($m){...}, $subject) 可動態計算替換內容。
  4. $limit 限制替換次數:-1 為無限制。

範例 1:樣板變數替換(陣列模式)

<?php
$pattern = ['/{title}/', '/{author}/', '/{url}/'];
$replace = ['代碼雲', '千手', 'https://codecloud.duapp.com/'];
$str = '標題:{title}<br>作者:{author}<br>地址:{url}';
echo preg_replace($pattern, $replace, $str);
// 標題:代碼雲<br>作者:千手<br>地址:https://codecloud.duapp.com/
?>

範例 2:UBB 碼轉 HTML(回呼處理屬性)

<?php
$str = '歡迎來到[url=https://example.com]我的部落格[/url]';
$html = preg_replace_callback(
    '/\[url=([^\]]+)\](.*?)\[\/url\]/is',
    function($m) {
        return '<a href="' . htmlspecialchars($m[1]) . '" target="_blank">' . $m[2] . '</a>';
    },
    $str
);
echo $html;
// 歡迎來到<a href="https://example.com" target="_blank">我的部落格</a>
?>

preg_split —— 多重分隔符分割

語法

array preg_split ( string $pattern, string $subject [, int $limit = -1 [, int $flags = 0 ]] )

常用旗標

  • PREG_SPLIT_NO_EMPTY:忽略空片段
  • PREG_SPLIT_DELIM_CAPTURE:保留分隔符於結果陣列
  • PREG_SPLIT_OFFSET_CAPTURE:附加位置索引

範例:多重標點分割

<?php
$str = 'one,two.three#four';
$parts = preg_split('/[,.#]/', $str, -1, PREG_SPLIT_NO_EMPTY);
print_r($parts);
// Array ( [0] => one [1] => two [2] => three [3] => four )
?>

修飾符速查

修飾符說明
i大小寫不敏感
m多行模式:^$ 匹配行首尾
s單行模式:. 匹配換行符
x擴展模式:忽略空白、允許註解
uUTF-8 模式(處理中文必加)
U非貪婪模式(預設貪婪)

效能與最佳實踐

  1. 能用字串函數就不用正則:strpos、str_replace、explode 為 C 實作,速度快數倍。
  2. 編譯快取:相同模式重複使用時,PHP 內部會快取編譯結果;極大量不同模式可考慮預先編譯。
  3. 避免災難性回溯:(.*)*、(a+)+ 等模式在長字串會指數級回溯,改用具體字元類別或具備長度限制。
  4. 定界符選擇:模式含 / 時改用 #...#、~...~ 避免大量跳脫。
  5. UTF-8 必加 u:否則中文字元會被視為多個位元組導致比對錯誤。

常見陷阱與除錯

Q: 為何 preg_match('/\d+/', 'abc') 回傳 0 而非 false?
A: 成功回傳 1,失敗回傳 0,錯誤回傳 false。嚴格判斷請用 === 0 或 === false。
Q: $matches 為何有時是多維陣列?
A: preg_match_all 預設 PREG_PATTERN_ORDER 產生多維;加 PREG_SET_ORDER 可得更直觀結構。
Q: 替換後字串出現亂碼?
A: 確認檔案編碼、資料庫連線編碼、HTML meta charset 均為 UTF-8,且模式加 u 修飾符。

總結

熟練掌握 preg_* 四大函數與修飾符,能以極少程式碼解決複雜字串處理需求。記住「先考慮非正則替代、再用正則」的原則,並在處理使用者輸入時嚴格驗證模式安全性,避免 ReDoS 攻擊。

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