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, @"(?<!\\)[\\](?!\\)", @"\\")
而不是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, @"(?<!\\)[\\](?!\\)", @"\\")
,它会做同样的替换,但前提是还没有转义。一行中的两个退格键保持不变。以上是关于C# 使用 Json.NET 读取 JSON 内容时保留转义序列的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 json.net 将 c# 通用列表转换为 json?