You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让SplFileObject的fgetcsv不将\视为转义字符?

解决SplFileObject::fgetcsv()将\视为转义字符的问题

PHP内置的fgetcsv(包括SplFileObject中的实现)默认会把反斜杠\当作转义字符,这会导致CSV文件中的\"被解析为文本的一部分,进而破坏整个CSV的结构,出现跨行解析、单元格内容混乱的问题。由于没有直接的配置项可以关闭这个转义行为,你可以通过以下两种方式解决:

方法1:预处理行内容,修正CSV转义规则

根据CSV标准(RFC 4180),双引号的正确转义方式是用另一个双引号包裹(即""),而非\"。我们可以先读取每行内容,将\"替换为"",再用str_getcsv解析:

$file = new SplFileObject('1.txt');
while (!$file->eof()) {
    $line = $file->fgets();
    // 将不符合标准的\"替换为标准的""
    $correctedLine = str_replace('\"', '""', $line);
    $row = str_getcsv($correctedLine, ';');
    print_r($row);
}

处理后,原内容中的"foo\"会被转为"foo"",解析后单元格内容为foo",同时不会破坏后续的CSV分隔结构。

方法2:自定义CSV解析逻辑,忽略反斜杠转义

如果需要完全绕过内置函数的转义逻辑,可以自己实现简单的CSV解析,仅将双引号作为单元格包裹标记,分号作为分隔符,忽略反斜杠的转义作用:

function customCsvParse($line, $delimiter = ';') {
    $rows = [];
    $currentCell = '';
    $inQuotes = false;
    
    $lineLength = strlen($line);
    for ($i = 0; $i < $lineLength; $i++) {
        $char = $line[$i];
        
        // 切换双引号包裹状态
        if ($char === '"') {
            $inQuotes = !$inQuotes;
            continue;
        }
        
        // 仅在未被双引号包裹时,将分号视为分隔符
        if ($char === $delimiter && !$inQuotes) {
            $rows[] = $currentCell;
            $currentCell = '';
            continue;
        }
        
        $currentCell .= $char;
    }
    // 添加最后一个单元格,去除换行符
    $rows[] = rtrim($currentCell, "\n\r");
    
    return $rows;
}

// 使用自定义解析函数处理文件
$file = new SplFileObject('1.txt');
while (!$file->eof()) {
    $line = $file->fgets();
    $row = customCsvParse($line, ';');
    print_r($row);
}

内容的提问来源于stack exchange,提问作者Roman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 22:32:06