Python解析块的实用工具?

3

我有一个文件,开头类似于:

databaseCons = {
    main = {
        database = "readable_name",
        hostname = "hostdb1.serv.com",
        instances= {
            slaves = {
                conns = "8"
            }
        }
        maxconns = "5",
        user = "user",
        pass = "pass"
    }
}

所以,我想将其解析为一个子dict字典,类似于: {'main': {'database': '可读名称', 'hostname': 'hostdb1.serv.com', 'maxconns': '5', 'instances': {'slave': {'maxCount': '8'}},'user': '用户', 'pass': '密码'}} 我认为以上内容很清晰明了...但如果不是,请随意进行编辑。基本上,我想要的等同于:
conns = '8'

slave = dict()
slave['maxCount'] = conns

instances = dict()
instances['slave'] = slave

database = 'readable_name'
hostname = 'hostdb1.serv.com'
maxconns = '5'
user = 'user'
pas = 'pass'
main = dict()
main['database'] = database
main['hostname'] = hostname
main['instances'] = instances
main['maxconns'] = maxconns
main['user'] = user
main['pass'] = pas

databaseCons = dict()
databaseCons['main'] = main

有没有模块可以处理这种解析?即使是我上面建议的看起来也很混乱.. 我想一定有更好的方法。


这是一个固定格式吗——也就是说,即使配置文件中的键相同且顺序相同,还是一个灵活的格式,可以出现任何键和任何嵌套级别,例如JSON? - abarnert
1
我认为你不会找到一个现成的解析器来解析这种语言。所以你有几个明显的选择。一个自定义的递归下降解析器不应该很难,你可以使用任何“100行以下的JSON解析器”作为指南,因为它在许多方面都是类似的。或者,一个递归下降转换到JSON可能需要比解析器更少的状态,然后你可以只需使用json.loadsijson作为后端。或者你可以描述语法,然后使用解析器库或解析器生成器(如PyParsing)应该很简单。 - abarnert
等等,实例块后面不是应该有一个逗号吗?那是打错字了吗? - jwilner
@Dietrich:或者任何在引号内的大括号。 - abarnert
1
如果你真的想使用eval(其实你真的不应该这样做),至少使用ast.literal_eval代替。这样可以消除安全漏洞,并且意味着如果你有意外的数据不符合这个模式,它更有可能失败或生成一个相对合理的错误信息,而不是使用eval时那样。 - abarnert
显示剩余14条评论
1个回答

2

这是一个适用于您的配置文件的pyparsing解析器:

from pyparsing import *

def to_dict(t):
    return {k:v for k,v in t}

series = Forward()
struct = Suppress('{') + series + Suppress('}')
value = quotedString.setParseAction(removeQuotes) | struct
token = Word(alphanums)
assignment = Group(token + Suppress('=') + value + Suppress(Optional(",")))
series << ZeroOrMore(assignment).setParseAction(to_dict)
language = series + stringEnd

def config_file_to_dict(filename):
    return language.parseFile(filename)[0]

if __name__=="__main__":
    from pprint import pprint
    pprint(config_file_to_dict('config.txt'))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接