【问题标题】:Parsing badly formatted json in Java在 Java 中解析格式错误的 json
【发布时间】:2014-05-07 14:42:47
【问题描述】:

我有一个格式错误的 JSON 字符串需要解析。 JSON 字符串的键没有用双引号括起来,字符串值用单引号而不是双引号括起来。

例子:

{ items: [
    { id: 1, name: 'test1' }, 
    { id: 2, name: 'test2' }
] }

解析这个 JSON 字符串的更好方法是什么?

1) 编写自定义解析器(如何?)

2) 尝试通过执行几个 string_replace 来修复 JSON 字符串

需要注意的是,JSON 字符串很长(大约 50kb)并且包含很多条目。

【问题讨论】:

  • 用锤子打鸡蛋,我可能会使用 javascript 引擎,因为这在 javascript 中是有效的,来为我做​​评估(可能是犀牛)。
  • @njzk2 我知道它在 JavaScript 中是有效的(它是为它设计的)。但我需要用Java解析它。有没有一个解析器可以很好地解析这个?
  • 我假设您没有切换到 XML 的选项。
  • @crownjewel82 不,我不知道。 JSON 按原样提供。
  • @mushroom:是的,因此建议使用 javascript 引擎,例如 rhino,它将评估它为 javascript 并返回一个 java 对象。但是如果你觉得 antlr 已经太重了……

标签: java json parsing


【解决方案1】:

Yaml 是(几乎)JSon 的超级集合,而且更宽容。它更接近你默认的。

String s = "{ items: [\n" +
        "    { id: 1, name: 'test1' }, \n" +
        "    { id: 2, name: 'test2' }\n" +
        "] }";
Map map = (Map) new Yaml().load(s);
System.out.println(map);

打印

{items=[{id=1, name=test1}, {id=2, name=test2}]}

顺便说一句,这就是它默认转储到 Yaml 的方式。

System.out.println(new Yaml().dump(map));

打印

items:
- {id: 1, name: test1}
- {id: 2, name: test2}

我使用了snakeyaml。您还可以将数据绑定到类

【讨论】:

    【解决方案2】:

    我认为Antlr4 是完成这项工作的最佳工具。

    您可以在这里找到一个example of a JSON grammar,您可以根据自己的目的轻松修改它,例如,STRING 词位可以从以下位置修改:

    STRING :  '"' (ESC | ~["\\])* '"' ;
    

    到:

    STRING :  '\'' (ESC | ~["\\])* '\'' ;
    

    您可以将pair 规则修改为如下所示:

    UNQUOTEDSTRING :  (ESC | ~["\\])* ;
    
    pair:   UNQUOTEDSTRING ':' value ;
    

    然后使用侦听器或访问者,您可以将修改后的 JSON 转换为正确的版本或直接将其解析为对象。

    【讨论】:

    • 谢谢,但我认为 Antlr4 对于这个目的来说有点太重了。我正在寻找最有效的方法。
    • @mushroom 我不确定是否有比修改 JSON 语法中的 3 行并为生成的解析器编写自定义侦听器/访问器更有效的方法...
    • 澄清一下,我指的不是易于实现,而是运行时的性能。如果 Antlr4 成为 Android 应用程序的一部分,会不会太过臃肿?
    • Antlr4 已经相当成熟,在很多生产就绪的项目(Pig、Hive 等)中都有使用。我不能保证它的性能,你必须自己测试不同的替代方案,但 JSON 语法小而简单,如果它很慢,我会感到惊讶。我不得不说@PeterLawrey 的解决方案在这种情况下可能更合适,并且一个合适的解析器可能比生成的解析器更有效。正如我常说的:测试两者并进行比较。
    猜你喜欢
    • 2016-05-30
    • 2016-08-09
    • 2013-08-19
    • 2017-09-10
    • 2010-10-29
    • 1970-01-01
    • 2016-02-05
    • 1970-01-01
    • 2016-05-25
    相关资源
    最近更新 更多