正则如何按需转义双引号:JSON大整数转字符串的嵌套场景问题
最优解决方案:使用PHP原生JSON扩展处理
直接操作JSON字符串的正则天生无法准确判断嵌套上下文,优先用解析后再处理的方案,完全规避格式错误问题:
// 第1步:解码JSON时直接将大整数转为字符串,参数JSON_BIGINT_AS_STRING会自动处理所有层级的大整数 $jsonData = json_decode($originalContent, true, 512, JSON_BIGINT_AS_STRING); // 第2步:重新编码为JSON,嵌套字符串内的引号会被自动转义 $result = json_encode($jsonData);
该方案处理你的示例时,输出完全符合预期:
- 顶层大整数会被转为
"3330922503411457761" - 嵌套在字符串内的JSON大整数会被转为
\\"3330922503411457761\\",不会破坏外层JSON格式
临时解决方案:正则修正(仅适用于无法解析JSON的场景)
改进原有正则,避免生成错误JSON
通过回调判断当前大整数所处的上下文,自动选择是否对新增引号转义:
$result = preg_replace_callback( '/:\s*(-?\d{16,})/', function ($matches) { // 统计当前匹配位置前未转义的双引号数量,判断是否处于字符串内部 $prevContent = substr($matches[0], 0, $matches[1][1] ?? 0); $unescapedQuoteCount = substr_count(str_replace('\\"', '', $prevContent), '"'); // 偶数引号代表在顶层JSON上下文,用普通引号;奇数代表在字符串内部,用转义引号 return $unescapedQuoteCount % 2 === 0 ? ': "' . $matches[1] . '"' : ': \\"' . $matches[1] . '\\"'; }, $originalContent );
修复已经被错误替换的JSON
如果已经生成了格式错误的JSON,可通过以下正则修正字符串内部未转义的引号:
$brokenJson = '{"example_json" : "{\\"example_bigint\\": "3330922503411457761"}"}'; $fixedJson = preg_replace_callback( '/"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"/s', function ($match) { return '"' . str_replace('"', '\\"', $match[1]) . '"'; }, $brokenJson );
注意:正则方案仅能覆盖常规场景,复杂嵌套下仍有出错概率,优先使用原生JSON处理方案
内容的提问来源于stack exchange,提问作者Alexey
相关产品推荐
相关产品推荐

