正則表達式看似晦澀,實則是我們熟悉的文件通配符 `?` `*` 的超集進化。本文從歷史溯源、核心概念、基本語法、實戰場景四個維度,帶你輕鬆跨越「正則恐懼症」,建立模式思維。
| 功能 | 通配符 | 正則表達式 |
| 單字符 | ? | . \d [a-z] \p{Han} |
| 多字符 | * | .* \d+ \w* .{3,10} |
| 選擇 | 不支援 | cat|dog (red|green|blue) |
| 分組捕獲 | 不支援 | (\d{4})-(\d{2}) → $1, $2 |
| 位置錨定 | 不支援 | ^ $ \b (?=...) |
| 數量精確控制 | 不支援 | {n} {n,m} +? |
文件搜索對比
# Shell 通配符
ls data?.dat # data1.dat data2.dat datax.dat
ls data*.dat # data.dat data1.dat data12.dat dataXYZ.dat
# 正則表達式 (grep -E)
grep -E '^data\d+\.dat$' # 精確匹配 data+數字+.dat
grep -E '^data(\d+)?\.dat$' # 可選數字
grep -E '^data[0-9a-f]{3}\.dat$' # 3位十六進制
核心概念三要素
- 原子:最小匹配單元(字符、字符類別、分組、斷言)
- 量詞:原子重複次數(
* + ? {n,m})
- 組合:序列、選擇、分組、錨定
模式 = 原子 + 量詞 + 組合
五大實戰場景
1. 數據驗證 (輸入過濾)
<?php
// 手機號
if (!preg_match('/^1[3-9]\d{9}$/', $_POST['mobile'])) {
die('手機號格式錯誤');
}
// 郵箱
if (!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
die('郵箱格式錯誤');
}
2. 文本提取 (信息抽取)
<?php
$log = '[2024-01-15 10:30:45] ERROR: Connection timeout (code=504)';
preg_match('/\[(.*?)\] (\w+): (.*?) \(code=(\d+)\)/', $log, $m);
// $m[1] = '2024-01-15 10:30:45'
// $m[2] = 'ERROR'
// $m[3] = 'Connection timeout'
// $m[4] = '504'
3. 字符串替換 (格式化/清洗)
<?php
// 手機號脫敏
echo preg_replace('/(\d{3})\d{4}(\d{4})/', '$1****$2', '13800138000'); // 138****8000
// 多空格壓縮
echo preg_replace('/\s+/', ' ', "Hello World\t\nGood"); // "Hello World Good"
// HTML 實體編碼
echo preg_replace('/&(?!#?\w+;)/', '&', 'Tom & Jerry'); // "Tom & Jerry"
4. 字符串分割 (結構化解析)
<?php
$csv = 'apple, "banana, split", orange, "grape""fruit"';
// 正確處理帶引號、含逗號、雙引號轉義的 CSV
$fields = preg_split('/,(?=(?:[^"]*"[^"]*")*[^"]*$)/', $csv);
// 結果: ['apple', ' "banana, split"', ' orange', ' "grape""fruit"']
5. 代碼重構/靜態分析
# 編輯器正則替換
# 將舊式數組語法轉為短語法
查找: array\((.*?)\)
替換: [$1]
# 提取所有類方法名
function\s+(\w+)\s*\(
# 查找 TODO/FIXME 註釋
(?://|#)\s*(TODO|FIXME|HACK|XXX):\s*(.*)
學習路徑建議
- 第 1 週:掌握字符類別 `[]`、預定義簡寫 `\d\w\s`、量詞 `*+?{}`、錨點 `^$\b`
- 第 2 週:理解分組 `()`、選擇 `|`、後向引用 `\1`、非捕獲 `(?:)`
- 第 3 週:攻克前瞻/後顧 `(?=)(?!)(?<=)(?
- 第 4 週:實戰項目:日誌分析器、表單驗證庫、模板引擎簡易實現
推薦工具
- 在線測試:regex101.com (支援 PCRE/JS/Python/Golang)、regexr.com
- 編輯器:VS Code 內建正則搜索 (Ctrl+Shift+F)、Regex Previewer 插件
- 可視化:Regulex (regexper.com) 生成鐵路圖
- 基準測試:regex101.com 右側 Regex Debugger 面板
避坑十誡
- 不要用正則解析 HTML/XML (用 DOM 解析器)
- 不要用正則驗證過於複雜的格式 (如完整 RFC 5322 郵箱)
- 警惕災難性回溯:避免嵌套量詞 `(a+)+`、交替重疊 `(a|a)*`
- 捕獲組只捕獲需要的,其餘用 `(?:)`
- 多行文本記得加 `m` 修飾符讓 `^$` 生效
- Unicode 文本必加 `u` 修飾符
- 固定字符串匹配用 `strpos`/`strstr` 更快
- 複雜模式加註釋 `(?x) ... # 註釋`
- 生產環境正則必寫單元測試覆蓋邊界情況
- 不確定時,拆解為多個簡單正則或改用程式邏輯
總結
正則表達式是文本處理的「瑞士軍刀」——功能強大但需謹慎使用。從通配符進化而來,核心優勢在於精確描述模式、提取結構化信息、批量文本變換。掌握基礎語法、理解引擎匹配原理、養成測試驗證習慣,即可駕馭這把利器。
- 上一篇文章: 正則表達式語法大全與運算符優先級權威指南
- 下一篇文章: PHP 函數自動化測試:參數組合生成與執行驗證框架
Copyright ©
程式碼之家 All Rights Reserved