
本文详解如何处理含多余空格、尾逗号、未引号日期等常见格式缺陷的 JSON 字符串,通过预清洗 + json_decode() 实现健壮转换,并提供错误排查与修复方案。
本文详解如何处理含多余空格、尾逗号、未引号日期等常见格式缺陷的 json 字符串,通过预清洗 + `json_decode()` 实现健壮转换,并提供错误排查与修复方案。
PHP 的 json_decode() 函数要求输入必须是严格符合 RFC 7159 标准的 JSON 字符串。但实际开发中(尤其来自第三方 API 或日志输出),常遇到如下典型非标准情况:
- 键名或字符串值使用中文/空格(如 "Cash Change Type" 合法,但需双引号包裹)
- 数值型字段未加引号却含逗号(如 "2022-05-06" 是合法字符串,但 2022-05-06(无引号)会被解析为 2022 减 5 减 6 = 2011)
- 末尾冗余逗号(如 },] 中的 ,)→ 严格 JSON 不允许数组/对象末尾逗号
- 多余空白与换行(虽不影响解析,但可能掩盖其他语法错误)
您提供的字符串存在两个关键问题:
- "Date": 2022-05-06 —— 未用双引号包裹,PHP 会尝试计算算术表达式,导致语法错误;
- },] 中的尾逗号 —— 违反 JSON 规范,json_decode() 直接返回 null 且 json_last_error() 报 JSON_ERROR_SYNTAX。
✅ 正确做法:先修复再解析,而非依赖“自动容错”:
<?php // 原始有问题的字符串(注意:此处需用单引号避免PHP解析转义)
$jsonString = '[{ "Account": "XXXXXXXXXXX", "Transaction ID": 3830251003, "Timestamp": "05/06/2022 17:21:40", "Date": 2022-05-06, "Delta": "50,000.00", "Amount": "50,000.00", "Cash Change Type": " Fund Transaction", "Currency": "USD", },]';
// 步骤1:移除对象/数组末尾的非法逗号(正则安全替换)
$jsonFixed = preg_replace('/,\s*([\]\}])/u', '$1', $jsonString);
// 步骤2:为未引号的日期字面量(如 2022-05-06)添加引号(仅当上下文明确为日期字符串时)
// ⚠️ 注意:此步需谨慎!通用方案建议由数据源修正。临时修复示例:
$jsonFixed = preg_replace('/"Date":\s*(\d{4}-\d{2}-\d{2})/', '"Date": "$1"', $jsonFixed);
// 步骤3:解析(第二个参数 true 强制返回关联数组)
$result = json_decode($jsonFixed, true);
// 步骤4:严格错误检查
if (json_last_error() !== JSON_ERROR_NONE) {
throw new InvalidArgumentException(
'JSON 解析失败: ' . json_last_error_msg() .
' | 原始字符串长度: ' . strlen($jsonString)
);
}
print_r($result);
// 输出:Array([0] => Array(['Account' => 'XXXXXXXXXXX', ..., 'Date' => '2022-05-06', ...]))
?>
? 重要注意事项:
- json_decode() 不会自动修复语法错误,必须确保输入合规;
- 使用 json_last_error() 和 json_last_error_msg() 是调试必选步骤;
- 对于生产环境,强烈建议推动上游系统输出标准 JSON(如 Date 字段统一为 "2022-05-06");
- 若需频繁处理脏数据,可封装为工具函数,但避免过度依赖正则修复——它无法解决所有语义歧义(如 Delta: 50,000.00 中的逗号是千分位还是小数点?应由业务层定义)。
最终,健壮的 JSON 处理 = 源头规范 + 输入校验 + 清洗兜底 + 显式错误反馈。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











