拆分由逗号分隔的 JSON blob 列表(忽略 JSON blob 中的逗号)[重复]
Posted
技术标签:
【中文标题】拆分由逗号分隔的 JSON blob 列表(忽略 JSON blob 中的逗号)[重复]【英文标题】:Split a list of JSON blobs delimited by commas (ignoring commas inside a JSON blob) [duplicate] 【发布时间】: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()。
【参考方案1】:
尝试使用您自己的规则来解析它是令人担忧的。您注意到 JSON 属性以逗号分隔的问题,但请记住 JSON 值可以包含字符串,其中可能包含大括号和逗号,甚至是与 JSON 结构无关的引号字符。
"John's comment": "I was all like, \"no way!\" :-"
要做到这一点,您需要编写一个能够处理所有 JSON 规则的解析器。你很可能会犯错误,而且不太可能从你付出的努力中获得太多价值。
我个人建议在字符串的任一侧添加括号并将整个内容反序列化为 JSON 数组的方法。
我还建议质疑将结果转换为字符串列表的要求:该要求是否基于某人的假设,即生成字符串列表比生成 JObject
s 列表或一些特定的序列化类型?
【讨论】:
关于字符串要求,JSON 是对象图的文本表示,因此,例如,如果您在输入的大括号中有空格并且它们不包含在输出中,那不是实质性区别。如果这对您很重要,那就是质疑要求的原因。 好点。至于需求的性质,我会将其编辑到帖子中以供参考。 @Alain:这种情况并没有让我有任何理由相信您实际上需要生成给定的确切 JSON 字符串。我首先在它周围加上括号并对其进行 JSON 序列化。我认为 JSON.NET 能够进行一些流式反序列化,因此您可能一次吃掉一个输入对象并将结果输出到一个单独的文件中。只有当您发现该方法存在严重的性能问题时,您才能考虑编写更优化的版本。 同意,虽然保留原始字符串不受影响会“很好”,但它对数据的最终使用应该没有有意义的影响。我的恐惧(根据过去的经验)是 Newtonsoft 会例如反序列化 UTC DateTimes 并在后面重新序列化为特定于区域设置的 DateTimes,这可能会产生微妙的影响(例如 UTC DateTime 的值为 DateTime.Min,并且区域设置为 -3 小时) JSON 没有任何时间类型,因此如果您只使用在Newtonsoft.Json.Linq
命名空间中定义的 LINQ to JSON 类型(JArray.Parse
会这样做),则不会发生转换,因为它们不会不能被解析为字符串。【参考方案2】:
您可以尝试拆分:
(?<=),(?=)
但这当然假设 JSON 字符串实际上并不包含,
的序列,例如:
"key":"For whatever reason, , literally exists in this string"
对于一组对象也会失败,例如:
"key1":["key2":"value2","key3":"value3"]
:-/
【讨论】:
以上是关于拆分由逗号分隔的 JSON blob 列表(忽略 JSON blob 中的逗号)[重复]的主要内容,如果未能解决你的问题,请参考以下文章
Java Regex - 拆分逗号分隔列表,但在括号内排除逗号