繁体   English   中英

解析现有的配置文件

[英]Parsing an existing config file

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

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

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

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

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

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

对于像这样的快速简单的解析, 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']]]]]]]

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

将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你会更快。

- 保罗

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

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

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

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

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

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

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

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

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

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

我在奶酪店搜索了一下,但我找不到任何有用的例子。 查看Examples页面,以及这个特定的解析器(它的语法类似于你的一些)。 我认为这应该可以帮助你自己写。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM