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

PHP 正則表達式處理函數全解析:preg_match、preg_match_all、preg_replace、preg_split

     編輯:PHP 綜合知識

前言

正則表達式需配合處理函數才能發揮作用。PHP 基於 PCRE 庫提供 preg_* 系列函數,性能優於 POSIX 正則。本文系統講解四大核心函數:匹配、全局匹配、替換、分割,含參數詳解、常見陷阱、實戰示例。

1. preg_match() — 單次匹配

int preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0)
  • 返回 1(匹配成功)、0(失敗)、false(錯誤)。
  • $matches[0] 為完整匹配,[1]... 為捕獲組。
  • PREG_OFFSET_CAPTURE 旗標可獲取匹配位置。

示例

<?php
$pattern = '/<b>(.*?)<\/b>/';
$str = '<b>welcome</b> <b>to</b> php';
if (preg_match($pattern, $str, $m)) {
    echo "首次匹配: {$m[0]}\n"; // welcome
    echo "捕獲組1: {$m[1]}\n";   // welcome
}
?>

2. preg_match_all() — 全局匹配

int preg_match_all(string $pattern, string $subject, array &$matches = null, int $flags = PREG_PATTERN_ORDER, int $offset = 0)
  • 返回所有匹配次數。
  • 默認 PREG_PATTERN_ORDER:$matches[0] 所有完整匹配,$matches[1] 所有第1組捕獲...
  • PREG_SET_ORDER:$matches[0] = 第一次匹配的所有組,結構更直觀。

示例

<?php
preg_match_all($pattern, $str, $m, PREG_SET_ORDER);
print_r($m);
/* 輸出:
Array
(
    [0] => Array ( [0]=> welcome [1]=> welcome )
    [1] => Array ( [0]=> to [1]=> to )
)
*/
?>

3. preg_replace() — 替換

mixed preg_replace(mixed $pattern, mixed $replacement, mixed $subject, int $limit = -1, int &$count = null)
  • $pattern $replacement $subject 均可為陣列,支援批量。
  • $limit 限制每個模式替換次數,-1 無限制。
  • $count 返回實際替換總次數。
  • 子模式引用:$replacement 中用 $1 ${2} 引用捕獲組(不要用 \1,僅模式中用)。
  • 修飾符 e (PREG_REPLACE_EVAL):PHP 7.0 移除,8.1 棄用,勿用。改用 preg_replace_callback()。

綜合示例

<?php
// 1. 簡單替換
echo preg_replace('/\d+/', '*', 'Age: 25, Year: 2024'); // Age: *, Year: *

// 2. 回調函數處理(替代 /e)
$str = 'php mysql';
echo preg_replace('/(php)|(mysql)/', fn($m) => strtoupper($m[0]), $str); // PHP MYSQL

// 3. 陣列批量
$patterns = ['/a/', '/b/'];
$replacements = ['A', 'B'];
echo preg_replace($patterns, $replacements, 'abc'); // ABc

// 4. 限制次數
echo preg_replace('/\s+/', '-', 'a b c', 1); // a-b c (只替換第一處)
?>

4. preg_split() — 正則分割

array preg_split(string $pattern, string $subject, int $limit = -1, int $flags = 0)
  • $limit > 0:最多返回 $limit 個元素,最後一個包含剩餘內容。
  • $limit < 0:返回除最後 abs($limit) 個元素外的所有。
  • 常用旗標:
    • PREG_SPLIT_NO_EMPTY:忽略空結果。
    • PREG_SPLIT_DELIM_CAPTURE:將捕獲組也包含在結果中。
    • PREG_SPLIT_OFFSET_CAPTURE:返回 [匹配內容, 偏移位置]。

示例

<?php
$str = '標題:PHP 正則;內容:preg 函數講解。';

// 1. 按中文標點分割,保留標點
print_r(preg_split('/([,。;:])/u', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY));
/* 輸出:
[標題, :, PHP 正則, ;, 內容, :, preg 函數講解, 。]
*/

// 2. 限制分割數
print_r(preg_split('/\s+/', 'a b c d', 2)); // [0]=>a [1]=>b c d

// 3. 獲取偏移
print_r(preg_split('/\b/', 'ab cd', -1, PREG_SPLIT_OFFSET_CAPTURE | PREG_SPLIT_NO_EMPTY));
/* 每個元素: [匹配文本, 在原字符串中的字節偏移] */
?>

常見陷阱與最佳實踐

陷阱正確做法
用 \1 引用捕獲組在 replacement 中用 $1 或 ${1}
模式中未轉義分隔符(如 /path/to/file/)用其他分隔符 #pattern# 或 ~pattern~
貪婪匹配導致過度吞噬用懶惰量詞 *? +? ?? 或具體字符類 [^>]*
大量數據用 preg_replace 替代 str_replace無正則需求時,str_replace 快 10 倍+
忽略 u 修飾符處理 UTF-8 中文模式末尾加 u:/漢字/u

總結

  • preg_match:判斷是否匹配、提取首次結果。
  • preg_match_all:提取所有匹配、解析結構化文本。
  • preg_replace:模式替換、格式化、清洗數據。
  • preg_split:複雜分割、保留分隔符、詞法分析。
  • 能用字符串函數(strpos, explode, str_replace)解決的,絕不寫正則。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved