为了账号安全,请及时绑定邮箱和手机立即绑定

用柯利布雷特斯解析文件

用柯利布雷特斯解析文件

达令说 2021-03-02 21:18:36
我需要用括号将信息解析为一个文件,例如:Continent{Name    EuropeCountry{Name    UKDog{Name    FiffiColour  Gray}Dog{Name    SmutColour  Black}}}这是我在Python中尝试过的from io import openfrom pyparsing import *import pprintdef parse(s):    return nestedExpr('{','}').parseString(s).asList()def test(strng):    print strng    try:        cfgFile = file(strng)        cfgData = "".join( cfgFile.readlines() )        list = parse( cfgData )        pp = pprint.PrettyPrinter(2)        pp.pprint(list)    except ParseException, err:        print err.line        print " "*(err.column-1) + "^"        print err    cfgFile.close()    print    return listif __name__ == '__main__':    test('testfile')但这失败并显示错误:testfileContinent^Expected "{" (at char 0), (line:1, col:1)Traceback (most recent call last):  File "xxx.py", line 55, in <module>    test('testfile')  File "xxx.py", line 40, in test    return listUnboundLocalError: local variable 'list' referenced before assignment  我需要做些什么才能使这项工作?是比pyparsing更好的解析器吗?
查看完整描述

2 回答

?
明月笑刀无情

TA贡献1828条经验 获得超4个赞

递归是这里的关键。尝试一些解决方法:


def parse(it):

    result = []

    while True:

        try:

            tk = next(it)

        except StopIteration:

            break


        if tk == '}':

            break

        val = next(it)

        if val == '{':

            result.append((tk,parse(it)))

        else:

            result.append((tk, val))


    return result

用例:


import pprint       


data = """

Continent

{

Name    Europe

Country

{

Name    UK

Dog

{

Name    Fiffi

Colour  Gray

}

Dog

{

Name    Smut

Colour  Black

}

}

}

"""


r = parse(iter(data.split()))

pprint.pprint(r)

...产生(Python 2.6):


[('Continent',

  [('Name', 'Europe'),

   ('Country',

    [('Name', 'UK'),

     ('Dog', [('Name', 'Fiffi'), ('Colour', 'Gray')]),

     ('Dog', [('Name', 'Smut'), ('Colour', 'Black')])])])]

请仅以此为起点,并随时根据需要改进代码(取决于数据,字典可能是更好的选择)。此外,示例代码无法处理格式错误的数据(特别是多余或丢失的数据}-我敦促您进行完整的测试;)


编辑:发现后pyparsing,我尝试了以下方法,这些方法似乎可以(更好)地工作,并且可以(更)容易地针对特殊需求进行定制:


import pprint

from pyparsing import Word, Literal, Forward, Group, ZeroOrMore, alphas


def syntax():

    lbr = Literal( '{' ).suppress()

    rbr = Literal( '}' ).suppress()

    key = Word( alphas )

    atom = Word ( alphas )

    expr = Forward()

    pair = atom | (lbr + ZeroOrMore( expr ) + rbr)

    expr << Group ( key + pair )


    return expr


expr = syntax()

result = expr.parseString(data).asList()

pprint.pprint(result)

生产:


[['Continent',

  ['Name', 'Europe'],

  ['Country',

   ['Name', 'UK'],

   ['Dog', ['Name', 'Fiffi'], ['Colour', 'Gray']],

   ['Dog', ['Name', 'Smut'], ['Colour', 'Black']]]]]


查看完整回答
反对 回复 2021-03-30
  • 2 回答
  • 0 关注
  • 154 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信