【发布时间】:2020-06-02 20:33:45
【问题描述】:
这是一个奇怪的问题。我得到了一个构思不当的输入字符串,它是一个 JSON blob 列表,用逗号分隔。例如:
string input = "{<some JSON object>},{JSON_2},{JSON_3},...,{JSON_n}"
我必须将其转换为 JSON 字符串的实际列表 (List<string>)。
就上下文而言,JSON 的不卫生“输入”列表是直接从磁盘上的 .txt 文件读取的,该文件由其他一些软件生成。我正在编写一个“适配器”以允许该数据被另一个知道如何解释列表中包含的单个 JSON 对象的软件使用。理想情况下,原始软件可以为每个 JSON 对象输出一个文件。
“显而易见”的解决方案(使用String.Split):
List<string> split = input.Split(',').ToList();
当然无法转义 JSON 对象 ({}) 本身中存在的逗号
我正在考虑一种手动方法 - 逐个字符地遍历字符串,并且仅当 { 的计数等于 } 的计数时才拆分出一个新元素。比如:
List<string> JsonBlobs = new List<string>();
int start = 0, nestingLevel = 0;
for (int i = 0; i < input.Length; i++)
{
if (input[i] == '{') nestingLevel++;
else if (input[i] == '}') nestingLevel--;
else if (input[i] == ',' && nestingLevel == 0)
{
JsonBlobs.Add(input.Substring(start, i - start));
start = i + 1;
}
}
(以上可能包含错误)
我还考虑在字符串 ([]) 的任一端添加 JSON 数组大括号,并让 JSON 序列化程序将其反序列化为 JSON 数组,然后一次重新序列化每个数组元素:
List<string> JsonBlobs = Newtonsoft.Json.Linq.JArray.Parse("[" + input + "]")
.Select<Newtonsoft.Json.Linq.JToken, string>(token => token.ToString()).ToList();
但这似乎过于昂贵,并且可能导致新序列化的 JSON 表示不完全等于原始字符串内容。
有更好的建议吗?
如果可能,我更愿意使用一些易于理解的内置库和/或 LINQ。正则表达式将是最后的手段,尽管漂亮的正则表达式解决方案也会很有趣。
【问题讨论】:
-
因此,如果您将它们反序列化为数组,然后将它们序列化为字符串列表,并且即使字符串与输入部分不完全匹配,对象在结构和值方面也是相同的,那是什么危害?这可能不是最有效的方法,但如果它有效,现在就这样做,以后再想出更好的方法。
-
从bing.com/…(FM - newtonsoft.com/json/help/html/…)中选择你喜欢的副本
-
现在 Json.NET 通过设置
JsonReader.SupportMultipleContent = true直接支持逗号分隔的 JSON 的反序列化;见Additional text encountered after finished reading JSON content:。如果您确实需要每个 blob 作为字符串,您可以将每个 blob 反序列化为JRaw,请参阅 Efficiently get full json string in JsonConverter.ReadJson()。