贝利信息

如何在 str_getcsv() 中正确转义分隔符以避免意外分割

日期:2026-01-07 00:00 / 作者:霞舞

`str_getcsv()` 的 `$escape` 参数不用于转义分隔符,而是用于转义 enclosure 内的引号;若需保留分隔符字符(如 `.`),应使用 enclosure(如单引号)将其包裹,而非依赖反斜杠转义。

str_getcsv() 是 PHP 中用于解析 CSV 风格字符串的内置函数,其签名如下:

array str_getcsv(
    string $string,
    string $separator = ",",
    string $enclosure = '"',
    string $escape = "\\"
)

需要特别注意:$escape 参数仅在 enclosure 字符内部生效,且仅用于转义 enclosure 本身(例如 "" 表示一个双引号),它不会让分隔符(如 .)在 enclosure 外被“跳过”或“忽略”。因此,以下调用:

str_getcsv("test\\.a.b", ".", "'", "\\");

并不会将 \. 视为“被转义的点”,因为 str_getcsv() 根本不解析反斜杠转义分隔符的语法——该行为不符合 RFC 4180 或 PHP 的实际实现。实际解析过程是:逐字符扫描,遇到未被 enclosure 包裹的 $separator 就切分;而 \\ 在此上下文中只是两个普通字符,\. 并不构成转义序列。

✅ 正确做法是:用 enclosure 将含分隔符的字段整体包裹,例如:

$result = str_getcsv("'test.a'.b", ".", "'", "\\");
var_dump($result);
// 输出:
// array(2) {
//   [0] => string(6) "test.a"
//   [1] => string(1) "b"
// }

此处 'test.a' 被单引号包围,因此中间的 . 不被视为分隔符,整个 'test.a' 被解析为第一个字段;随后的 .b 中,开头的 . 触发分割,得到第二项 "b"。

⚠️ 注意事项:

? 总结:不要试图用 $escape “转义分隔符”,而应通过合理使用 enclosure 控制字段边界。这是 CSV 解析的通用原则,也是 str_getcsv() 的设计前提。