如何预修复不可修改外部来源JSON的无效转义序列供JSON.Net解析
通用损坏JSON预修复实现方案
零散做Replace替换属于被动补漏模式,只要数据提供方输出新的非法格式,就得新增对应的替换规则。通用方案的核心逻辑是:所有清洗动作只作用于JSON双引号包裹的字符串值内部,完全不触碰JSON本身的结构语法部分,从规则层面一次性覆盖两类常见非法问题。
匹配的两类问题处理规则
JSON的结构语法部分(大括号、冒号、逗号、边界双引号)不会产生非法内容,所有异常都出现在字符串值区块内,对应两类问题的统一处理逻辑:
- 未转义控制字符:直接移除字符串值内所有ASCII值在0x00-0x1F区间的原始控制字符(包括制表符、原始换行、回车等),和你之前接受的“删除制表符”的处理逻辑完全一致
- 非法转义序列:字符串值内出现的所有反斜杠,只要后面跟随的字符不在JSON标准合法转义白名单中,就直接删除这个多余的反斜杠,仅保留后面的原字符
- JSON标准规定的合法转义字符仅包含:
"、\、/、b、f、n、r、t、u,可以参考下面的白名单定义:HashSet<char> validEscapeChars = new() {'"', '\\', '/', 'b', 'f', 'n', 'r', 't', 'u'}; - 处理连续反斜杠时要正确计数:比如连续两个反斜杠
\\属于合法转义(代表一个字面反斜杠),后续字符就属于普通字符串内容,不能把第二个反斜杠误判为非法转义的起点
- JSON标准规定的合法转义字符仅包含:
具体执行流程
- 逐字符遍历原始JSON文本,通过匹配“未被反斜杠转义的双引号”,精准定位所有字符串值区块的起止位置
- 进入字符串区块后逐字符做清洗:移除原始控制字符,判断每个反斜杠后的字符是否属于合法转义范围,不属于就去掉多余的反斜杠
- 全文本清洗完成后,再调用
JObject.Parse解析处理后的内容
方案相比零散替换的优势
- 不需要提前预判所有可能的非法格式:不管数据提供方写出多少种非标准转义序列(比如
\$、\&、\x),只要不在合法转义白名单里就统一做去反斜杠处理,不会出现补漏跟不上的问题 - 不会误伤结构内容:所有清洗动作都限定在字符串值内部,不会破坏JSON本身的键名、语法分隔符、合法转义序列
- 规则灵活可调整:如果后续需要保留某个特定的转义格式,只需要把对应字符加入合法转义白名单即可,不需要改动整体遍历逻辑
注意:如果遇到字符串值内的双引号完全没有转义的极端结构损坏场景,这个基础遍历方案的边界判断会失效,但这类问题已经不属于你当前遇到的两类转义/控制字符问题的范畴。
内容的提问来源于stack exchange,提问作者Matt Burland
相关产品推荐
相关产品推荐

