You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Newtonsoft.Json反序列化含正则转义的JSON正则数组

问题:类JSON格式正则数组反序列化失败

我在数据库单个字段中存储了类JSON格式的正则表达式数组,示例为:["^.*\/Car($|\/$|\?|\/\?)"]。使用Newtonsoft.Json将其反序列化为string[]对象时,始终抛出Newtonsoft.Json.JsonReaderException。

测试代码

public static void Main(string[] args)
{
    // 正常工作的示例
    string patterns = @"[""^.*\/Car""]";
    var x = JsonConvert.DeserializeObject<string[]>(patterns);
    Console.WriteLine(x.First()); // 输出 ^.*/Car

    // 报错示例:正则中的\?导致JSON解析失败
    patterns = @"[""^.*\/Car\?""]";
    x = JsonConvert.DeserializeObject<string[]>(patterns); // 抛出Newtonsoft.Json.JsonReaderException: 'Bad JSON escape sequence: \?. Path '', line 1, position 12.'
    Console.WriteLine(x.First());

    // 报错示例:JsonEncodedText.Encode无效
    patterns = @"[""^.*\/Car\?""]";
    x = JsonConvert.DeserializeObject<string[]>(JsonEncodedText.Encode(patterns).ToString()); // 抛出Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: \. Path '', line 1, position 2.'
    Console.WriteLine(x.First());

    // 正常工作的示例:将\?转义为\\?
    patterns = @"[""^.*\/Car\\?""]";
    x = JsonConvert.DeserializeObject<string[]>(patterns); // 输出 .*/Car\?
    Console.WriteLine(x.First());

    // 最终需要解决的场景
    // 正则表达式为 ^.*\/Car($|\/$|\?|\/\?)
    patterns = @"[""^.*\/Car($|\/$|\?|\/\?)"]";
    x = JsonConvert.DeserializeObject<string[]>(patterns); // 抛出异常
    Console.WriteLine(x.First());
}

问题原因

核心冲突是JSON转义规则与正则转义规则不兼容:

  • JSON仅允许特定的转义序列(如\"、\\、\/等),\?不属于JSON合法转义,直接解析会触发错误;
  • 数据库中存储的内容本质是不符合标准JSON规范的字符串——正则中的反斜杠未按照JSON要求转义为\\。

解决方案:预处理字符串修复JSON格式

由于无法修改数据库存储,必须先将非法的转义序列修正为JSON合法格式,再执行反序列化。

基础修复方案

直接将字符串中所有单个反斜杠替换为两个反斜杠,确保JSON解析器能正确识别:

public static void Main(string[] args)
{
    // 从数据库读取的原始类JSON字符串
    string rawPatterns = @"[""^.*\/Car($|\/$|\?|\/\?)"]";
    
    // 预处理:修复JSON转义,将单个\替换为\\
    string fixedJson = rawPatterns.Replace(@"\", @"\\");
    
    // 正常反序列化
    var regexArray = JsonConvert.DeserializeObject<string[]>(fixedJson);
    Console.WriteLine(regexArray.First()); // 输出 ^.*\/Car($|\/$|\?|\/\?)
}

精准修复方案(避免破坏合法JSON转义)

如果原始字符串中存在JSON合法转义(如\"表示双引号),直接全局替换会破坏这些合法序列。此时可以用正则表达式只替换非法的转义序列:

public static void Main(string[] args)
{
    string rawPatterns = @"[""^.*\/Car($|\/$|\?|\/\?)"]";
    
    // 正则替换:仅修复非JSON标准的转义序列
    // 匹配规则:单个反斜杠,且后面不是JSON允许的转义字符("、\、/、b、f、n、r、t、u)
    string fixedJson = Regex.Replace(rawPatterns, @"(?<!\\)\\(?![""\\/bfnrtu])", @"\\");
    
    var regexArray = JsonConvert.DeserializeObject<string[]>(fixedJson);
    Console.WriteLine(regexArray.First());
}

为什么之前的方法无效?

  • JsonEncodedText.Encode():该方法是将普通.NET字符串编码为JSON格式,但你传入的是已经错误格式化的类JSON字符串,它会把整个内容当作普通文本再次转义,导致格式彻底混乱;
  • Regex.Escape():该方法用于转义正则表达式的特殊字符,和JSON转义规则无关,无法解决JSON解析错误。

内容的提问来源于stack exchange,提问作者josibu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 12:05:34