2016-08-12 35 views
3

使用pyparsing,我需要指定两个表达式可以以任意顺序以及两个大括号之间的任意数字出现。以下是我的代码。以任何顺序和数字处理一系列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 ...或fieldExpr ... msgExpr ...)出现。一些例子:

  1. msgExpr msgExpr fieldExpr fieldExpr fieldExpr msgExpr
  2. fieldExpr msgExpr fieldExpr fieldExpr msgExpr fieldExpr
  3. msgExpr fieldExpr fieldExpr

我知道,必须有办法做到这一点,但I`我错过了它。

在此先感谢

回答

2

(首先,在未来,请准备好你的问题的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'], {}) 
+1

我改变了我试过msgBody = openBrace + pp.ZeroOrMore(msgExpr | fieldExpr)+ closeBrace,但这仍然不起作用。我一定还有其他的东西,我错过了。我包含更多的代码,因为我认为这可能不是问题。 – XYZ

+0

@XYZ - 你需要更具体地说明这个表达式“不起作用”。 – PaulMcG

+0

没关系。我有一个与我想象不同的问题。谢谢 – XYZ

相关问题