c# - 用于解析 JSON 对象数组的正则表达式?

标签 c# .net regex json

我正在尝试将 JSON 对象数组解析为 C# 中的字符串数组。我可以从 JSON 对象中提取数组,但无法将数组字符串拆分为单个对象的数组。

我有这个测试字符串:

string json = "{items:[{id:0,name:\"Lorem Ipsum\"},{id:1,name" 
            + ":\"Lorem Ipsum\"},{id:2,name:\"Lorem Ipsum\"}]}";

现在我正在使用以下正则表达式将项目拆分为单个对象。现在它们是 2 个独立的正则表达式,直到我用第二个正则表达式解决问题:

Regex arrayFinder = new Regex(@"\{items:\[(?<items>[^\]]*)\]\}"
                                 , RegexOptions.ExplicitCapture);
Regex arrayParser = new Regex(@"((?<items>\{[^\}]\}),?)+"
                                 , RegexOptions.ExplicitCapture);

arrayFinder 正则表达式按我预期的方式工作,但是由于我不明白的原因,arrayParser 正则表达式根本不起作用。我想要它做的就是将各个项目拆分成它们自己的字符串,这样我就得到了这样的列表:

{id:0,name:"Lorem Ipsum"}
{id:1,name:"Lorem Ipsum"}
{id:2,name:"Lorem Ipsum"}

这个列表是string[] 数组还是GroupMatch 集合并不重要,但我被难住了如何让对象 split 。使用上面声明的 arrayParserjson 字符串,我已经尝试了这段我认为不会成功的代码:

string json = "{items:[{id:0,name:\"Lorem Ipsum\"},{id:1,name" 
            + ":\"Lorem Ipsum\"},{id:2,name:\"Lorem Ipsum\"}]}";

Regex arrayFinder = new Regex(@"\{items:\[(?<items>[^\]]*)\]\}"
                                 , RegexOptions.ExplicitCapture);
Regex arrayParser = new Regex(@"((?<items>\{[^\}]\}),?)+"
                                 , RegexOptions.ExplicitCapture);

string array = arrayFinder.Match(json).Groups["items"].Value;
// At this point the 'array' variable contains: 
// {id:0,name:"Lorem Ipsum"},{id:1,name:"Lorem Ipsum"},{id:2,name:"Lorem Ipsum"}

// I would have expected one of these 2 lines to return 
// the array of matches I'm looking for
CaptureCollection c = arrayParser.Match(array).Captures;
GroupCollection g = arrayParser.Match(array).Groups;

谁能看出我做错了什么?我完全坚持这一点。

最佳答案

平衡括号从字面上看是一种无法用正则表达式处理的语言的教科书示例。 JSON 本质上是平衡括号加上一堆其他东西,大括号被圆括号代替。在hierarchy of formal languages , JSON 是一种上下文无关的语言。正则表达式无法解析上下文无关语言。

一些系统提供正则表达式的扩展,可以处理平衡表达式。然而,它们都是丑陋的 hack,它们都不可移植,而且它们最终都是错误的工具。

在专业工作中,您几乎总是会使用现有的 JSON 解析器。如果您想出于教育目的自己动手,那么我建议您从支持 + - */( ) 的简单算术语法开始。 (JSON 有一些转义规则,虽然并不复杂,但会使您的第一次尝试变得比需要的更难。)基本上,您需要:

  1. 将语言分解为符号字母表
  2. 根据识别语言的那些符号编写上下文无关文法
  3. 将文法转换为乔姆斯基范式,或足够接近以简化第 5 步
  4. 编写一个词法分析器,将原始文本转换为您输入的字母表
  5. 编写一个递归下降解析器,获取词法分析器的输出,对其进行解析,并生成某种输出

这是几乎所有大学的典型三年级 CS 作业。

下一步是找出在递归解析器中触发堆栈溢出需要多复杂的 JSON 字符串。然后看看其他可以编写的解析器类型,你就会明白为什么在现实世界中必须解析上下文无关语言的任何人都使用像 yacc 或 antlr 这样的工具而不是手动编写解析器。

如果这比您想要的要多,那么您应该放心地使用现成的 JSON 解析器,并满足于您学到了一些重要且有用的东西:正则表达式的限制。

关于c# - 用于解析 JSON 对象数组的正则表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/408570/

相关文章:

c# - Razor 中 foreach 中的 html 和代码的混合

c# - 写入文件并处理重复条目

c# - 在编辑器 onload 中显示 Datepicker 而不是需要用户选择

c# - 创建包时找不到文件

.net - 具有纹理的 CUDA 中的 GPU 性能

c# - HttpContent.ReadAsAsync 在哪里?

java - 正则表达式模式不会匹配任何内容

c# - 如何确保在 OWIN 应用程序中进行 WS 联合身份验证后使用用户的原始请求 URL

java - 在Java中获取字符串整数结尾的最佳方法?

regex - 使用 sed 替换 URL 模式失败