使用 PHP 解析其中包含 JSON 的 CSV
Parse a CSV with a JSON in it using PHP
简介
我有一个 CSV 文件,其中每个字段都用双引号引起来 ("
)。每行的最后一个字段是 JSON 字符串表示形式。我想编写一个 PHP 脚本来解析 CSV 文件,然后解析 JSON 字符串。这就是我现在拥有的。
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"}
试试这个:
$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":""}"
}
简介
我有一个 CSV 文件,其中每个字段都用双引号引起来 ("
)。每行的最后一个字段是 JSON 字符串表示形式。我想编写一个 PHP 脚本来解析 CSV 文件,然后解析 JSON 字符串。这就是我现在拥有的。
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"}
试试这个:
$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":""}"
}