解析现有的配置文件

时间:2009-06-15 13:43:23

标签: python parsing config

我有一个以下格式的配置文件:

protocol sample_thread {
    { AUTOSTART 0 }
    { BITMAP thread.gif }
    { COORDS {0 0} }
    { DATAFORMAT {
        { TYPE hl7 }
        { PREPROCS {
            { ARGS {{}} }
            { PROCS sample_proc }
        } }
    } } 
}

真实文件可能没有这些确切的字段,我宁愿在解析之前不必描述数据的结构是解析器。

我已经找了其他配置文件解析器,但我发现没有一个能够接受这种语法的文件。

我正在寻找一个可以解析这样的文件的模块,有什么建议吗?

如果有人好奇,有问题的文件是由Quovadx Cloverleaf生成的。

8 个答案:

答案 0 :(得分:11)

pyparsing对于快速简单的解析非常方便。最低限度的是:

import pyparsing
string = pyparsing.CharsNotIn("{} \t\r\n")
group = pyparsing.Forward()
group << pyparsing.Group(pyparsing.Literal("{").suppress() + 
                         pyparsing.ZeroOrMore(group) + 
                         pyparsing.Literal("}").suppress()) 
        | string

toplevel = pyparsing.OneOrMore(group)

用它作为:

>>> toplevel.parseString(text)
['protocol', 'sample_thread', [['AUTOSTART', '0'], ['BITMAP', 'thread.gif'], 
['COORDS', ['0', '0']], ['DATAFORMAT', [['TYPE', 'hl7'], ['PREPROCS', 
[['ARGS', [[]]], ['PROCS', 'sample_proc']]]]]]]

从那里你可以根据需要变得更复杂(从字符串中单独解析数字,查找特定的字段名称等)。以上是非常通用的,只是寻找字符串(定义为除“{”和“}”之外的任何非空格字符)和{}分隔的字符串列表。

答案 1 :(得分:2)

将Brian的pyparsing解决方案再迈出一步,您可以使用Dict类为此格式创建一个准解串器:

import pyparsing

string = pyparsing.CharsNotIn("{} \t\r\n")
# use Word instead of CharsNotIn, to do whitespace skipping
stringchars = pyparsing.printables.replace("{","").replace("}","")
string = pyparsing.Word( stringchars )
# define a simple integer, plus auto-converting parse action
integer = pyparsing.Word("0123456789").setParseAction(lambda t : int(t[0]))
group = pyparsing.Forward()
group << ( pyparsing.Group(pyparsing.Literal("{").suppress() +
    pyparsing.ZeroOrMore(group) +
    pyparsing.Literal("}").suppress())
    | integer | string )

toplevel = pyparsing.OneOrMore(group)

sample = """
protocol sample_thread {
    { AUTOSTART 0 }
    { BITMAP thread.gif }
    { COORDS {0 0} }
    { DATAFORMAT {
        { TYPE hl7 }
        { PREPROCS {
            { ARGS {{}} }
            { PROCS sample_proc }
        } }
    } } 
    }
"""

print toplevel.parseString(sample).asList()

# Now define something a little more meaningful for a protocol structure, 
# and use Dict to auto-assign results names
LBRACE,RBRACE = map(pyparsing.Suppress,"{}")
protocol = ( pyparsing.Keyword("protocol") + 
             string("name") + 
             LBRACE + 
             pyparsing.Dict(pyparsing.OneOrMore(
                pyparsing.Group(LBRACE + string + group + RBRACE)
                ) )("parameters") + 
             RBRACE )

results = protocol.parseString(sample)
print results.name
print results.parameters.BITMAP
print results.parameters.keys()
print results.dump()

打印

['protocol', 'sample_thread', [['AUTOSTART', 0], ['BITMAP', 'thread.gif'], ['COORDS', 

[0, 0]], ['DATAFORMAT', [['TYPE', 'hl7'], ['PREPROCS', [['ARGS', [[]]], ['PROCS', 'sample_proc']]]]]]]
sample_thread
thread.gif
['DATAFORMAT', 'COORDS', 'AUTOSTART', 'BITMAP']
['protocol', 'sample_thread', [['AUTOSTART', 0], ['BITMAP', 'thread.gif'], ['COORDS', [0, 0]], ['DATAFORMAT', [['TYPE', 'hl7'], ['PREPROCS', [['ARGS', [[]]], ['PROCS', 'sample_proc']]]]]]]
- name: sample_thread
- parameters: [['AUTOSTART', 0], ['BITMAP', 'thread.gif'], ['COORDS', [0, 0]], ['DATAFORMAT', [['TYPE', 'hl7'], ['PREPROCS', [['ARGS', [[]]], ['PROCS', 'sample_proc']]]]]]
  - AUTOSTART: 0
  - BITMAP: thread.gif
  - COORDS: [0, 0]
  - DATAFORMAT: [['TYPE', 'hl7'], ['PREPROCS', [['ARGS', [[]]], ['PROCS', 'sample_proc']]]]

我认为通过pyparsing你会得到更快的速度。

- 保罗

答案 2 :(得分:1)

我会尝试回答我认为缺失的问题...

配置文件有多种格式。有众所周知的格式,如* .ini或apache配置 - 这些格式往往有很多解析器可用。

然后有自定义格式。这就是你的看法(它可能是你以前从未见过的一种定义明确的格式 - 但直到你知道它是什么并不重要)。

我会从这个来自的软件开始,看看他们是否有可以加载/生成这些文件的编程API。如果没有什么是显而易见的,请给Quovadx打电话。有可能有人已经解决了这个问题。

否则你可能会自己创建自己的解析器。

假设您的样本代表完整的示例,为此格式编写解析器并不是非常困难。它是值的层次结构,其中每个节点可以包含值的值或子层次结构。一旦定义了值可以包含的基本类型,解析器就是一个非常简单的结构。

你可以使用像Lex / Flex这样的东西或者用你选择的语言中的直接解析器来快速写出来。

答案 3 :(得分:1)

你可以轻松地在python中编写一个脚本,将其转换为python dict,格式看起来几乎像分层名称值对,只有问题似乎是 Coards {0 0},其中{0 0}不是名称值对,而是列表 那么谁知道格式中还有其他类似的案例 我认为你最好的选择是为这种格式制作规范并编写一个简单的python脚本来阅读它。

答案 4 :(得分:1)

您的配置文件与JSON非常相似(几乎用“[”和“]”替换所有“{”和“}”)。大多数语言都有内置的JSON解析器(PHP,Ruby,Python等),如果没有,可以使用库来处理它。

如果您无法更改配置文件的格式,则可以将所有文件内容作为字符串读取,并通过您喜欢的任何方式替换所有“{”和“}”字符。然后你可以将字符串解析为JSON,然后设置。

答案 5 :(得分:0)

我在Cheese Shop上搜索了一下,但我找不到任何有用的例子。检查Examples页面和this特定解析器(它的语法类似于你的)。我认为这应该可以帮助你自己编写。

答案 6 :(得分:0)

查看LEX and YACC。有点学习曲线,但他们可以为任何语言生成解析器。

答案 7 :(得分:-2)

也许您可以编写一个简单的脚本,将您的配置转换为xml文件,然后使用lxml,Beatuful Soup或其他任何东西读取它?例如,您的转换器可以使用PyParsing或正则表达式。