【问题标题】:Parse a CSV with a JSON in it using PHP使用 PHP 解析带有 JSON 的 CSV
【发布时间】:2015-09-23 15:23:33
【问题描述】:

简介

我有一个 CSV 文件,其中每个字段都用双引号 (") 括起来。每行中的最后一个字段是 JSON 字符串表示。我想编写一个解析 CSV 文件并随后解析 JSON 字符串的 PHP 脚本。这就是我现在所拥有的。

while (($line = fgetcsv($handle, 1000000, ";", '"')) !== false)
{
    // Another loop to loop over the fields
    // ...
    parse_json(end($line));
}

private function parse_json($json_string)
{
    if (!empty($json_string))
    {
        $json = json_decode($json_string, true);
        $msg = sprintf("The following description is not in proper JSON format: %s", $json_string);
        if (is_null($json))
        {
            // The function json_decode returns null if the string is not properly JSON formatted.
            throw new Exception($msg);
        }
    }
}

通过 CSV 文件中的以下行,我在 PHP 中得到以下数组。

"A";"B";"C";"D";"E";;"{""Name"":""Richard B Mephisto""}"
array ('Name' => 'Richard B Mephisto');

问题描述

当我想在 JSON 字符串的一个值中允许双引号时,问题就开始了。对于 JSON,我需要用反斜杠转义双引号,而对于 CSV,我需要用另一个双引号转义双引号。如果我想要以下数组,CSV 文件和解析器应该如何?

array ('Name' => 'Richard "B" Mephisto');

尝试失败

1) 在 CSV 文件中使用以下行。

"A";"B";"C";"D";"E";;"{""Name"":""""Richard B Mephisto""""}"

解析 JSON 时,在调用 json_decode 之前,将每个 "" 替换为 /"。这在这种情况下有效,但我还需要允许空字符串。

"A";"B";"C";"D";"E";;"{""Name"":""}"

这些也将被此解决方案替换。

2) 在 CSV 文件中使用反斜杠。原则上,JSON 字符串应如下所示:

{"Name": "Richard \"B\" Mephisto"}

所以我在 CSV 文件中试试这个:

"A";"B";"C";"D";"E";;"{""Name"":\""Richard B Mephisto\""}"

结果:

以下描述的 JSON 格式不正确:{"JSON_key":"Richard \"B\"" Mephisto""}"

不知何故,它与转义字符和双引号一起无法正常工作。

3) 转义 CSV 中的反斜杠。

"A";"B";"C";"D";"E";;"{""JSON_key"":""Richard \\""B\\"" Mephisto""}"

结果:

The following description is not in proper JSON format: {"JSON_key":"Richard \\"B\\" Mephisto"}

【问题讨论】:

    标签: php json parsing csv escaping


    【解决方案1】:

    试试这个:

    $in = '"A";"B";"C";"D";"E";;"{""Name"":""Richard \""B\"" Mephisto""}";"{""Name"":""""}"';
    $out = str_getcsv($in, ';', '"', '"'); 
    var_dump($out);
    

    结果:

    array(8) {
      [0]=>
      string(1) "A"
      [1]=>
      string(1) "B"
      [2]=>
      string(1) "C"
      [3]=>
      string(1) "D"
      [4]=>
      string(1) "E"
      [5]=>
      string(0) ""
      [6]=>
      string(33) "{"Name":"Richard \"B\" Mephisto"}"
      [7]=>
      string(11) "{"Name":""}"
    }
    

    【讨论】:

    • 谢谢!我以为我有这个,但后来我注意到你在 getcsv 中有一个单独的'"'。我把行改成fgetcsv($handle, 1000000, ";", '"', '"')逐行读取文件,现在好像可以了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-07
    • 2018-12-02
    • 2016-04-25
    • 2020-03-28
    • 2017-04-08
    相关资源
    最近更新 更多