函數語法
array preg_split(string $pattern, string $subject, int $limit = -1, int $flags = 0)
| 參數 | 說明 |
$pattern | 正規表達式模式(需含分隔符,如 /.../) |
$subject | 要分割的字串 |
$limit | 最大分割片段數,-1/0=不限制 |
$flags | 旗標組合(可用 | 串接) |
常用 Flags
| 常數 | 效果 |
PREG_SPLIT_NO_EMPTY | 忽略空片段(連續分隔符不產生空元素) |
PREG_SPLIT_DELIM_CAPTURE | 將捕獲群組內容也加入結果陣列 |
PREG_SPLIT_OFFSET_CAPTURE | 回傳 [片段, 位移] 陣列而非單純字串 |
基本範例
1. 以空白字元分割單字(計算平均長度)
<?php
$wordCount = $wordLength = 0;
if ($fh = fopen('novel.txt', 'r')) {
while (!feof($fh)) {
if ($line = fgets($fh)) {
// \s+ 匹配一或多個空白字元(空格、Tab、換行)
$words = preg_split('/\s+/', $line, -1, PREG_SPLIT_NO_EMPTY);
foreach ($words as $word) {
$wordCount++;
$wordLength += strlen($word);
}
}
}
fclose($fh);
}
printf("平均單字長度:%.2f 字元 (共 %d 字)", $wordLength / $wordCount, $wordCount);
?>
2. 多分隔符分割
<?php
$text = "apple, orange; banana | grape";
// 以逗號、分號、管線符號(前後可有空白)分割
$fruits = preg_split('/\s*[,;|]\s*/', $text);
print_r($fruits);
/*
Array
(
[0] => apple
[1] => orange
[2] => banana
[3] => grape
)
*/
?>
3. 保留分隔符
<?php
$str = "a,b;c|d";
// 捕獲群組 () 會將分隔符也包含在結果中
$parts = preg_split('/(\s*[,;|]\s*)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
print_r($parts);
/*
Array
(
[0] => a
[1] => ,
[2] => b
[3] => ;
[4] => c
[5] => |
[6] => d
)
*/
?>
4. 取得位移資訊
<?php
$str = "hello world";
$parts = preg_split('/\s+/', $str, -1, PREG_SPLIT_OFFSET_CAPTURE);
print_r($parts);
/*
Array
(
[0] => Array ( [0] => hello, [1] => 0 )
[1] => Array ( [0] => world, [1] => 6 )
)
*/
?>
實務應用範例
CSV 簡易解析(處理引號內逗號)
<?php
function parseCsvLine($line) {
// 分割:逗號,但不分割雙引號內的逗號
// 使用負向前瞻:,(?=(?:[^"]*"[^"]*")*[^"]*$)
return preg_split('/,(?=(?:[^"]*"[^"]*")*[^"]*$)/', $line);
}
$line = '1,"張三, 先生",25,"台北市,信義區"';
print_r(parseCsvLine($line));
/*
Array
(
[0] => 1
[1] => "張三, 先生"
[2] => 25
[3] => "台北市,信義區"
)
*/
?>
CamelCase / PascalCase 拆分單字
<?php
function splitCamelCase($str) {
// 在小寫字母後面、大寫字母前面分割
return preg_split('/(?<=[a-z])(?=[A-Z])/', $str);
}
print_r(splitCamelCase('getUserName')); // [get, User, Name]
print_r(splitCamelCase('XMLHttpRequest')); // [XML, Http, Request]
?>
效能與替代方案
| 場景 | 建議函數 | 理由 |
| 固定字串分割 | explode() | 無正規表示式開銷,速度快 3-10 倍 |
| 單字元分割 | str_split() | 專為字元分割優化 |
| 複雜模式/多分隔符 | preg_split() | 功能最強大 |
| CSV 標準解析 | str_getcsv() | 內建處理引號、逸出字元 |
常見錯誤
- 忘記分隔符:
preg_split('\s+', $str) ❌ → preg_split('/\s+/', $str) ✅
- 未使用
PREG_SPLIT_NO_EMPTY 導致連續空白產生空元素。
$limit 設為 1 時代表「不分割,回傳原字串陣列」。