使用pyparsing,我需要指定两个表达式可以在两个大括号之间以任意顺序和任意数字出现。下面是我的代码。

import pyparsing as pp

def updateList(someList):
    def parseAction(str, loc, tokens):
        someList.append(tokens[0])
    return parseAction

msgNameList = []
ident = pp.Word(pp.alphanums + "_" + ".")
openBrace = pp.Suppress(pp.Literal("{"))
closeBrace = pp.Suppress(pp.Literal("}"))
fieldKw = pp.Keyword("field")
fieldExpr = fieldKw + ident + ident
msgKw = pp.Suppress(pp.Keyword("msg"))
msgName = ident.setParseAction(updateList(msgNameList))
msgExpr = pp.Forward()
msgBody = (openBrace + (pp.ZeroOrMore(fieldExpr) & pp.ZeroOrMore(msgExpr)) + closeBrace)
msgExpr << msgKw + msgName + pp.Optional(msgBody)

testStr1 = "msg msgNameA {msg msgNameAB {field type2 field2} field type1 field1}"
msgExpr.parseString(testStr1)
print msgNameList

msgNameList = []
testStr2 = "msg msgNameA {field type1 field1 msg msgNameAB {field type2 field2}}"
msgExpr.parseString(testStr2)
print msgNameList

产生这种输出:
['msgNameA', 'msgNameAB', 'type2', 'field2', 'type1', 'field1']
[]

注意,我只在解析msgName表达式时添加到msgNameList。(它的最终表达式和解析函数将更加复杂。)
我想要的两个测试字符串的输出是:
['msgNameA', 'msgNameAB']

我确信我对msgBody的解析表达式是不正确的,但是我不知道如何在pyparsing中表达我需要的内容。在大括号中,msgExpr或fieldExpr可以以任意顺序和任意数字出现(msgExpr。。。字段表达式。。。或fieldExpr。。。msgExpr。一些例子:
msgExpr msgExpr fieldExpr fieldExpr msgExpr
fieldExpr msgExpr fieldExpr fieldExpr msgExpr fieldExpr
msgExpr fieldExpr fieldExpr
我知道一定有办法,但我错过了。
提前谢谢

最佳答案

(首先,在将来,请准备一个MCVE的问题。你问题的要点是
使用pyparsing,我需要指定两个表达式可以在两个大括号之间以任意顺序和任意数字出现。下面是我的代码。
所以请准备一个只包含足够细节的问题。)
假设我们从

from pyparsing import *

foo = Literal('foo')
bar = Literal('bar')

然后指定“任意顺序和括号之间的任意数字”
openBrace = Suppress(Literal("{"))
closeBrace = Suppress(Literal("}"))

foo_or_bar = foo | bar
content = ZeroOrMore(foo_or_bar)
exp = openBrace + content + closeBrace

现在我们可以检查:
In [40]: exp.parseString('{foo}')
Out[40]: (['foo'], {})

In [41]: exp.parseString('{foobarfoo}')
Out[41]: (['foo', 'bar', 'foo'], {})

关于python - 以任何顺序和数量处理一系列pyparsing表达式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38925138/

10-09 18:40