当 CSV 有几个双引号“”“或整行用引号括起来时,如何使用 fgetcsv()?

How to use fgetcsv() when the CSV has several double quotes """" or if the entire line is wrapped in quotes?

提问人:Avatar 提问时间:5/31/2022 最后编辑:Avatar 更新时间:5/31/2022 访问量:396

问:

我们导入到服务器的某些CSV文件无法正确解析。

我们正在使用 PHP 的 fgetcsv() 读取 CSV 文件:

while (($line = fgetcsv($file)) !== false) { ... }

但是,当 CSV 行用引号括起来(并且其中包含两个双引号)时,例如:

"first entry,"""","""",Data Chunk,2022-05-30"

fgetcsv() 函数无法正确处理该行,并将 视为一个条目。first entry,"""","""",Data Chunk,2022-05-30

我们如何确保该函数确实被视为一个单独的条目,并将其他部分解释为空条目?first entry""""


在更多的研究中,我发现:

包含双引号 (“)、换行符 (CRLF) 和逗号的字段必须用双引号括起来。

如果用双引号 (“) 括起来的字段包含双引号字符,则字段内的双引号前面必须加上另一个双引号作为转义序列。

这可能是我们在这里面临的问题。


CSV 的更完整数据示例:

Allgemeines
Subject,Body,Attachment,Author,Created At,Updated At
"Hello everyone, this is a sample. Kind regards,"""","""",Author name (X),2022-05-30 14:54:32 UTC,2022-05-30 14:54:37 UTC"
","""",https://padlet-uploads.storage.googleapis.com/456456456/testfile.docx,Author name (X),2022-05-15 13:53:04 UTC,2022-05-15 13:54:40 UTC"
",""Hello everyone!"

This is some fun text.
More to come.
Another sentence.
And more text.

Even more text

See you soon.




","",Author name (X),2021-07-22 09:41:06 UTC,2021-07-23 16:12:42 UTC
""
Important Things to Know in 2022
Subject,Body,Attachment,Author,Created At,Updated At
"","

01.01.2022 First day of new year
02.02.2202 Second day of new year

Please plan ahead.
","",Author name (X),2021-07-22 09:58:19 UTC,2022-03-24 14:16:50 UTC
""

注意:行以双引号开头,以双引号和回车符以及换行符结束。

php fgetcsv

评论

4赞 RiggsFolly 5/31/2022
好吧,如果您的数据不符合 CSV 的规则,则无法读取它。您可以考虑对数据进行预解析,以重新格式化所有违反规则的位fgetcsv()
1赞 Bijay Regmi 5/31/2022
用更可解析的东西替换不是更容易吗?""""
2赞 Sammitch 5/31/2022
在您更新问题以将其包装在另一层双引号中而不转义里面的引号之前,它是有效的 CSV。你应该要求你的数据提供者也许不要对你造成这场噩梦。
1赞 RiggsFolly 5/31/2022
好吧,您的问题有一半是不是 CSV :)看起来您可能需要阅读一行,然后进行一些文本操作和分解,以将数据拆分为可用的可单独引用字段,
2赞 RiggsFolly 5/31/2022
好吧,因为你不能在双引号字符串中使用双引号,所以你将不得不要求解释你应该如何处理这些数据,或者可能为你提供一个选项,例如将其下载为JSON。没有规定说即使是有钱人也不能时不时地搞砸它multi-million company

答:

1赞 Avatar 5/31/2022 #1

事实证明,CSV数据已损坏。

用户在 Excel 中搞砸了 CSV,正如评论中所述,可能覆盖了原始 CSV。导致双重转义。

对于面临相同问题的任何人:

  1. 不要浪费时间尝试使用自定义解析器恢复损坏的CSV文件。

  2. 要求用户授予您访问原始 CSV 导出网站的权限,并自行生成 CSV。

  3. 检查 CSV 完整性。请参阅下面的代码。

    $file = fopen($csvfile, 'r');

    // validate if all the records have same number of fields, empty lines (count 1), full entry (count 6) - depends on your CSV structure

    $length_array = array();

    while (($data = fgetcsv($file, 1000, ",")) !== false) 
    {
        // count number of entries
        $length_array[] = count($data);
    };

    $length_array = array_unique($length_array);

    // free memory by closing file
    fclose($file);
    
    // depending on your CSV structure it is $length_array==1 or $length_array==2
    if (count($length_array) > 2) 
    {
        // count mismatch
        return 'Invalid CSV!';
    }

👍