正則表達式是程式開發的基礎利器,掌握捕獲組與非捕獲組的差異,能讓模式匹配更精準、結果處理更靈活。本文透過實際代碼範例,詳細說明 PHP 中各類捕獲組的語法、行為與實戰技巧。
(pattern)最常見的形式,匹配並記錄結果,支援巢狀,組編號從左至右遞增。
$regex = '/(ab(c)+)+d(e)?/';
$str = 'abccde';
$matches = [];
if (preg_match($regex, $str, $matches)) {
print_r($matches);
}
/* 結果:
Array (
[0] => abccde
[1] => abcc
[2] => c
[3] => e
) */
(?P<name>pattern)賦予子組名稱,結果陣列同時包含數字鍵與名稱鍵,方便直接索引。
$regex = '/(?P<group1>\w(?P<group2>\w))abc(?P<group3>\w)45/';
$str = 'fsabcd45';
$matches = [];
if (preg_match($regex, $str, $matches)) {
print_r($matches);
}
/* 結果:
Array (
[0] => fsabcd45
[group1] => fs
[1] => fs
[group2] => s
[2] => s
[group3] => d
[3] => d
) */
\num在模式中引用前面捕獲組的值,\1 代表第一組,\2 代表第二組等。
$regex = '/(\w)(\w)\2\1/';
$str = 'abba';
$matches = [];
if (preg_match($regex, $str, $matches)) {
print_r($matches);
}
/* 結果:
Array ( [0] => abba [1] => a [2] => b ) */
注意:反向引用在單引號字串中才會正確解析,雙引號需轉義。
\k<name>引用命名捕獲組的值。
$regex = '/(?P<name>\w)abc\k<name>/';
$str = 'fabcf';
preg_match_all($regex, $str, $matches);
print_r($matches);
/* 結果:
Array (
[0] => Array ( [0] => fabcf )
[name] => Array ( [0] => f )
[1] => Array ( [0] => f )
) */
(?:pattern)僅分組匹配,不記錄結果,不佔用組編號,適合僅需結構分組的場合。
預查不消耗字元,只做條件判斷。
| 類型 | 語法 | 說明 |
|---|---|---|
| 正向肯定 | (?=pattern) | 後面必須匹配 pattern |
| 正向否定 | (?!pattern) | 後面不可匹配 pattern |
| 反向肯定 | (?<=pattern) | 前面必須匹配 pattern |
| 反向否定 | (?<!pattern) | 前面不可匹配 pattern |
$regx = '/(?<=a)bc(?=d)/'; $str = "abcd ebcd abce ebca"; preg_match_all($regx, $str, $matches); print_r($matches); /* 結果: Array ( [0] => Array ( [0] => bc ) ) */
預查不佔字元寬度。/HE(?=L)LLO/ 能匹配 HELLO(實際匹配到 HELLO),但 /HE(?=L)LO/ 無法匹配 HELLO,因為預查後緊接 LO 只佔 4 字元,而目標有 5 字元。
熟練掌握這些機制,將大幅提升您處理字串解析與驗證的能力。