如何匹配错误JSON中双引号值内部的所有双引号?
修复格式错误JSON的正则匹配方案
问题根源
你现有正则的缺陷:
- 第一个正则里的
[^\,\"]*是单个字符排除,遇到值内的逗号(比如orange字段里的green, purple)就会中断匹配,导致后续的cyan周围引号无法被捕获。 - 第二个正则的负向后行断言
(?<!(.*):\"(.*))逻辑完全错误——它会排除所有处于:"之后的位置,直接违背你要匹配值内引号的需求。
正确正则实现
核心思路
只匹配处于:"之后、且下一个有效结束标记(",或"})之前的",同时避开下一个键的起始:"。
通用正则(支持大部分语言)
(?<=:\")(?:(?!\"(?:\,|\})).)*?\K\"(?=(?:(?!:\").)*?\"(?:\,|\}))
JavaScript兼容版本(JS不支持\K)
/(:\"(?:(?!\"(?:\,|\})).)*?)\"((?:(?!:\").)*?\"(?:\,|\}))/g
逻辑拆解
- 前置边界:
(?<=:\")确保当前位置在值的起始标记:"之后。 - 值内范围限制:
(?:(?!\"(?:\,|\})).)*?匹配值内任意字符,但不碰到结束的",或"},避免越界到下一个键值对。 - 目标捕获:
\K(或捕获组)只保留需要替换的嵌套"。 - 后置验证:
(?=(?:(?!:\").)*?\"(?:\,|\}))确保当前引号之后,直到结束标记前没有其他键的起始:",防止误匹配。
替换验证
用你的示例字符串测试:
let x = '{"my_text":"hello "world"","test2":"tree","blue":"red "yellow","orange":"green, purple "cyan""}'; // JS版本替换 let fixedX = x.replace(/(:\"(?:(?!\"(?:\,|\})).)*?)\"((?:(?!:\").)*?\"(?:\,|\}))/g, '$1\\"$2');
替换后得到合法JSON:
{"my_text":"hello \"world\"","test2":"tree","blue":"red \"yellow\"","orange":"green, purple \"cyan\""}
额外建议
如果服务器返回的错误格式更复杂(比如值内有多层嵌套引号+特殊字符组合),纯正则可能会失效,建议:
- 先将
"替换为真实双引号" - 使用专门的JSON修复工具处理,比正则更稳定可靠
内容的提问来源于stack exchange,提问作者Z0q
相关产品推荐
相关产品推荐

