C# 使用 Json.NET 读取 JSON 内容时保留转义序列

Posted

技术标签:

【中文标题】C# 使用 Json.NET 读取 JSON 内容时保留转义序列【英文标题】:C# preserve escape sequence when reading JSON content using Json.NET 【发布时间】:2016-03-16 02:37:48 【问题描述】:

使用 Json.NET 读取 JSON 内容时,C# 保留转义序列

给定以下 json 文本内容:

 "Pattern": "[0-9]*\t[a-z]+" 

这体现在一个简单的类中:

public class Rule

    public string Pattern  get; set; 

    public bool Test(string text)
    
        return new Regex(Pattern).IsMatch(text);
        

它是这样反序列化的:

var json = System.IO.File.ReadAllText("file.json");
var rule = JsonConvert.DeserializeObject<Rule>(text);

Pattern 的值应该是一个正则表达式模式。问题是,一旦读取内容,“\t”转义序列会立即作为一个制表符的转义字符应用,导致字符串值:[0-9]* [a-z]+

我的理解是内容格式有些不正确,因为它应该看起来像这样:[0-9]*\\t[a-z]+ 在 Json 内容中有效,转义反斜杠以便可以保留并导致实际模式[0-9]*\t[a-z]+。但是该文件是用户编辑的,我希望能够松散地解释内容,假设应该保留反斜杠(并且不会转换转义序列)。

我尝试实现自定义JsonConverter,但在查找令牌时,该值已解析。

FIDDLE

【问题讨论】:

也许我错了,但这些模式不是等效的吗? \t 或选项卡应该与正则表达式给出相同的结果,不是吗? user edited。难道你不能假设如果用户能够编辑JSON 文件,他就知道需要转义反斜杠吗? @Rob 这可能是真的,是的,在\t 的情况下,但是由于正则表达式的复杂性,变化越来越小 @MichaelMairegger 是的,我可以,但我知道用户的工作方式,他们使用像 regexhero.net 这样的工具并复制正则表达式模式,更改它,再次复制。 ...一个复杂的模式可以有多次出现。如果他们也可以将其粘贴到我们的配置文件中,那就太好了,粘贴值时出错的可能性很高。 [* 唯一的例外是不包含 " 这会破坏字符串,但我们不希望在正则表达式中包含它] 我相信问题出在其他地方:在文件中,\t 是文字 \ 和文字 t,应该读作 "\\t" C 字符串。 【参考方案1】:

我已经尝试了下面的代码,它可以工作...也许我不明白问题出在哪里,或者您可以提供一个不适用于此的示例:

StreamReader s= new StreamReader(@"test.txt");
string json = s.ReadToEnd();
json=json.Replace("\\","\\\\");
JObject obj = JObject.Parse(json);
string pattern = obj["Pattern"].ToString();
bool test = Regex.IsMatch("1    a", pattern);

test.txt 仅包含以下内容:

 "Pattern": "[0-9]*\t[a-z]+" 

编辑 正如Thomasjaworsky 所说,最好使用Regex.Replace(json, @"(?&lt;!\\)[\\](?!\\)", @"\\") 而不是json=json.Replace("\\","\\\\"); ,它将执行相同的替换,但前提是尚未转义。行中的两个退格键保持不变。

【讨论】:

好的,所以我没有选择一个好的例子。 \t 实际上就像标签一样工作,你是对的。但是,如果您将 \t 替换为 \. 以匹配句点,例如,Parse 命令将失败。 1.a。此外,例如,如果您想在某处记录模式(例如到控制台)Console.WriteLine(pattern),它将呈现到选项卡。 好的。我知道了。如果在string json = s.ReadToEnd(); 之后添加此行:json=json.Replace("\\","\\\\");,它在我的示例中不起作用吗?这样Console.WriteLine(pattern) 也可以使用 感谢 Pikoh 有效!由于它应用于整个内容的缺点,我不能真正将其仅隔离到正则表达式模式。 是的......你必须在解析它之前这样做,但我不认为这是一个大问题,因为它只是将'\'替换为'\\',不会影响还要别的吗。很高兴它对你有用! :) 我不是在做Replace("\\","\\\\"),而是Regex.Replace(json, @"(?&lt;!\\)[\\](?!\\)", @"\\"),它会做同样的替换,但前提是还没有转义。一行中的两个退格键保持不变。

以上是关于C# 使用 Json.NET 读取 JSON 内容时保留转义序列的主要内容,如果未能解决你的问题,请参考以下文章

c#开源工具(或者C# 开源框架)

如何将弱类型 JSON 转换为 C# 可读对象

.NET 中的 LINQ to JSON

如何使用 json.net 将 c# 通用列表转换为 json?

如何使用 json.net 将 c# 通用列表转换为 json?

.NET(C#) Json.Net(newtonsoft)使用LINQ查询JSON数据