解析复杂配置文件的最佳方法

时间:2015-03-05 17:02:38

标签: python parsing grammar

我需要使用Python解析复杂的配置文件。我应该注意到这些文件的格式是我无法改变的,而是必须与之共存。

文件的基本结构是:

Keyword1
"value1"
thisisirrelevantforkeyword1
Keyword2
"first", "second", "third"
1, 2, 3

Keyword3
2, "whatever"
firstparam, 1
secondparam, 2
again_not_relevant

最终,这个输出应该是一个JSON字符串。

让我解释一下:

  • 每个关键字都有自己的规则。
  • 值位于关键字后面的行中。
  • 例如, Keyword1 有一个值,即字符串 value1 value1 之后的行无关紧要。
  • 例如, Keyword2 有两个参数,第一个是字符串列表,第二个是整数列表。
  • 例如, Keyword3 具有可变数量的参数,由 Keyword3 之后的第一行中的第一个整数表示。因此,与 Keyword3 相关的参数是列表 2,“无论什么”,以及以下两行中的两个列表。

有一组固定的关键字,它们有自己的规则。当然,我原则上可以对整个事情进行硬编码,这会导致大量的代码重复。此外,对于新关键字或更改单个关键字的规则,这将非常不灵活。

我宁愿准备一个包含所有关键字的CSV文件,以及如何定义的规则,然后将其用作更通用的解析器函数的输入。

所以我的问题是: - 如何以简单的方式指定规则?我确定有这个标准,但绝对不知道从哪里开始寻找。 - 那我怎么能用这个语法来解析文件并生成我的JSON?

我知道这是一个非常具体,特殊和复杂的事情;所以我已经感谢指示正确的方向,因为我觉得有点失落,我不确定从哪里开始寻找。

1 个答案:

答案 0 :(得分:1)

我认为你可以为你的选项提供一些有特殊规则的课程。

类似的东西:

class OptionBase(object):
    def __init__(self, name, **options):
        self.name = name
        self.raw_config_lines = []

    def parse_line(self, line):
        line = line.strip()
        if line:
            self.raw_config_lines.append(line)

    def get_config(self):
        raise Exception('Not Implemented')


class SimpleOption(OptionBase):
    def __init__(self, name, **options):
        super(SimpleOption, self).__init__(name, **options)
        self.expected_format = options.get('expected_format', str)

    def parse_line(self, line):
        if len(self.raw_config_lines):
            raise Exception('SimpleOption can only have one value')
        else:
            super(SimpleOption, self).parse_line(line)

    def get_config(self):
        return None if not self.raw_config_lines else self.expected_format(self.raw_config_lines[0])


class SomeComplexOption(OptionBase):
    def parse_line(self, line):
        #some special code which verify number of lines, type of args etc.

    def get_config(self):
        #some code to transform raw_line in another format