將字串依分隔符切割為陣列是 PHP 最常見的操作之一。核心函數 explode() 效能最佳但功能單一;preg_split() 支援正則表達式功能最強;str_split() 依長度切割;mb_split() 支援多位元組編碼。本文詳細比較四大函數語法、效能、適用場景與常見陷阱。
<?php
// 基本語法
array explode(string $separator, string $string, int $limit = PHP_INT_MAX): array
// 範例
$csv = 'apple,banana,orange,grape';
$fruits = explode(',', $csv);
// ['apple', 'banana', 'orange', 'grape']
// limit 參數控制回傳元素數
$str = 'a,b,c,d';
explode(',', $str, 2); // ['a', 'b,c,d'] 正數:最多 N 個元素
explode(',', $str, -1); // ['a', 'b', 'c'] 負數:排除最後 N 個元素
explode(',', $str, 0); // ['a,b,c,d'] 0 視同 1
// 空字串分割
explode(',', ''); // [''] 含 1 個空元素
?>
ValueError (PHP 8.0+) / 警告 (舊版)。<?php
// 基本語法
array preg_split(string $pattern, string $subject, int $limit = -1, int $flags = 0): array
// 範例:多種分隔符
$str = 'apple,banana;orange|grape';
$fruits = preg_split('/[,;|]/', $str);
// ['apple', 'banana', 'orange', 'grape']
// 範例:分割於一或多個空白字元
$words = preg_split('/\s+/', 'hello world\tPHP\nis\tawesome');
// ['hello', 'world', 'PHP', 'is', 'awesome']
// 旗標 flags
preg_split('/:/', 'a:b:c', -1, PREG_SPLIT_NO_EMPTY); // 移除空元素
preg_split('/:/', 'a:b:c', -1, PREG_SPLIT_DELIM_CAPTURE); // 保留分隔符
preg_split('/:/', 'a:b:c', -1, PREG_SPLIT_OFFSET_CAPTURE); // 返回 [元素, 偏移量]
// Unicode 支援:需 u 修飾符
$zh = '你好,世界';
preg_split('/\p{P}/u', $zh); // 依標點分割,支援中文標點
?>
explode 慢 5-20 倍(視正則複雜度)。PREG_SPLIT_NO_EMPTY 極實用,自動過濾連續分隔符產生的空元素。<?php // 基本語法 array str_split(string $string, int $length = 1): array $str = 'Hello'; str_split($str); // ['H','e','l','l','o'] str_split($str, 2); // ['He','ll','o'] // ⚠️ 中文會被拆成單一位元組,導致亂碼 $zh = '你好'; str_split($zh); // ['\xE4','\xBD','\xA0','\xE5','\xA5','\xBD'] (UTF-8 每字 3 bytes) ?>
<?php
// mb_split 需 mbstring 擴充,使用 Oniguruma 正則引擎
// 語法類似 preg_split,但預設支援多位元組
$zh = '你好,世界';
mb_split(',', $zh); // ['你好', '世界']
mb_split('\p{P}', $zh); // 依標點分割 (需正則支援)
// 現代推薦:preg_split + u 修飾符 (PCRE 8.32+ 內建 Unicode 支援)
preg_split('/\p{P}/u', $zh); // 同樣效果,效能通常優於 mb_split
?>
| 函數 | 耗時 (ms) | 記憶體 | 備註 |
|---|---|---|---|
explode(',', $str) | ~15 | 低 | 基準 |
preg_split('/,/', $str) | ~85 | 中 | 簡單正則 |
preg_split('/\s+/', $str) | ~220 | 中高 | 複雜正則 |
mb_split(',', $str) | ~110 | 中 | 多位元組引擎 |
str_split($str, 10) | ~30 | 高 | 產生 10 萬元素陣列 |
<?php
// explode 需自行過濾
$arr = array_filter(explode(',', 'a,,b,'), fn($v) => $v !== '');
// preg_split 一步到位
$arr = preg_split('/,/', 'a,,b,', -1, PREG_SPLIT_NO_EMPTY);
// ['a', 'b']
?>
<?php
// 解析標記語言、保留標點
$parts = preg_split('/(\d+)/', 'Item123Price456', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
// ['Item', '123', 'Price', '456']
?>
<?php // 正確處理引號、逗號、換行符 $csv = 'a,"b,c",d'; $fields = str_getcsv($csv); // ['a', 'b,c', 'd'] ?>
<?php
// ✅ 正確:preg_split 配合 u 修飾符
$chars = preg_split('//u', '你好PHP', -1, PREG_SPLIT_NO_EMPTY);
// ['你', '好', 'P', 'H', 'P']
// ✅ 正確:mb_str_split (PHP 7.4+)
$chars = mb_str_split('你好PHP');
// ['你', '好', 'P', 'H', 'P']
// ❌ 錯誤:str_split 會拆碼位元組
?>
explode() 是 90% 場景的最佳選擇:簡單、快速、記憶體友善。遇到複雜分割需求時,preg_split() 提供正則威力,記得善用 PREG_SPLIT_NO_EMPTY 旗標。處理多位元組字串務必加上 u 修飾符或使用 mb_str_split()。切記:CSV/TSV 專用解析器 才能正確處理引號與轉義,切勿自行用 explode/preg_split 解析。