【问题标题】:How to parse a file in INI/JSON-like non-standard format?如何解析类似 INI/JSON 的非标准格式的文件?
【发布时间】:2012-02-12 10:11:50
【问题描述】:

假设我有一个以下(非标准)格式的文本文件:

xxx { a = v1; b = v2} yyy { a = v3; c = v4 }

我无法将其更改为任何标准(INI/XML/YAML 等)格式。

现在我想在xxx 部分(即v1)中找到属性a 的值。在 Java/Groovy 中最简单的方法是什么?

【问题讨论】:

  • 我宁愿使用 YAML 或 JSON。有准备使用的解析器。为什么要发明另一种格式?您甚至可以创建有效的 Groovy 脚本并在运行时从文件中运行它,获取真实的对象和道具。
  • @StephenC 这不是重复的,因为链接的问题询问 INI 文件。这个问题询问的是 INI-like 格式。
  • 您将需要更详细地定义您的格式,例如1. 在关闭} 之前是否总是没有分号? 2.{}之间可以换行吗?等等。您可能必须为此格式编写自定义解析器。

标签: java parsing groovy


【解决方案1】:

使用 Groovy,您可以利用 ConfigSlurper。

但是,您首先需要将一个有效值映射在一起,这样它就不会在试图找出 v1, v2, v3, etc 是什么时感到窒息:

这似乎有效:

def input = '''xxx { a = v1; b = v2 }
              |yyy { a = v3; c = v4 }'''.stripMargin()

def slurper = new ConfigSlurper()

// Find all words 'w' and make a map of [ w1:'w1', w2:'w2', ... ]
slurper.binding = ( ( input =~ /\w+/ ) as List ).collectEntries { w -> [ (w):w ] }

def result = slurper.parse( input )
println result

打印出来:

[xxx:[a:v1, b:v2], yyy:[a:v3, c:v4]]

(Groovy 1.8.4)

【讨论】:

    【解决方案2】:

    首先,您给出了一个示例,但没有指定格式。在继续之前,您需要掌握格式的完整规范。或者如果没有,您需要查看生成它的代码,然后对规范进行逆向工程。

    (如果您尝试基于一个小示例来实现,那么您的解析器很有可能会遇到不符合您直觉模式的现实示例。)

    完成后,您可以寻找可以处理您的格式的现成解析器。如果幸运的话,它可能与 INI、JSON 或 YAML 或其他东西足够接近,以便相应的解析器(大部分)工作。

    但很有可能不会,您需要编写自己的解析器。有多种方法可以做到这一点,例如:

    • 您可以将文件分成几行并使用正则表达式“解析”每一行。
    • 您可以使用带有适当分隔符的扫描仪解析文件。
    • 您可以使用解析器生成器来实现词法分析器和解析器。
    • 您可以手动实现一个简单的词法分析器和解析器。
    • 可能有特定于 Groovy 的解决方案。

    实际上,正确的选择取决于实际格式的简单或复杂程度。我们无法从一个例子中看出这一点。

    【讨论】:

      【解决方案3】:

      对于真正的 INI 格式文件:What is the easiest way to parse an INI file in Java?

      在我看来,您在此处显示的内容更像 JSON,而不是 INI 格式。也许看看 JSON 解析库。这里的事实是您没有使用已建立的格式,因此您可能不会使用已建立的格式解析器。您最好的选择可能是将您正在处理的文件(如果可能)重构为众所周知的格式。除非万不得已,否则不要尝试重新发明轮子。

      【讨论】:

        【解决方案4】:

        如果您处理的是非标准格式,则可能不会有现成的解决方案。以下是您可能想要研究的一些方法:

        • 如果格式简单,写自定义recursive descent parser
        • 编写一个过滤器,将您的格式转换为 INI、JSON 等,并使用现有的库
        • 创建一个与您的格式相匹配的groovy DSL 并将您的文件作为 groovy 脚本执行
        • 使用解析器生成器工具(如 antlrparboiled)根据语言规范创建解析器

        【讨论】:

          猜你喜欢
          • 2021-04-04
          • 2021-08-29
          • 2017-12-31
          • 1970-01-01
          • 2014-01-30
          • 2012-01-29
          • 1970-01-01
          • 1970-01-01
          • 2018-06-24
          相关资源
          最近更新 更多