以任何顺序和数字处理一系列 pyparsing 表达式
handling a sequence of pyparsing expressions in any order and number
使用 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 ...)。一些例子:
- msgExpr msgExpr fieldExpr fieldExpr fieldExpr msgExpr
- fieldExpr msgExpr fieldExpr fieldExpr msgExpr fieldExpr
- msgExpr fieldExpr fieldExpr
我知道一定有办法做到这一点,但我想念它。
提前致谢
(首先,以后请准备一个MCVE你的问题。你的问题的要点是
Using pyparsing, I need to specify that two expressions can occur in any order and in any number between two braces. Below is my code.
所以请准备一个仅包含足够详细信息的问题。)
假设我们从
开始
from pyparsing import *
foo = Literal('foo')
bar = Literal('bar')
然后指定"any order and any number between the brackets"
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'], {})
使用 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 ...)。一些例子:
- msgExpr msgExpr fieldExpr fieldExpr fieldExpr msgExpr
- fieldExpr msgExpr fieldExpr fieldExpr msgExpr fieldExpr
- msgExpr fieldExpr fieldExpr
我知道一定有办法做到这一点,但我想念它。
提前致谢
(首先,以后请准备一个MCVE你的问题。你的问题的要点是
Using pyparsing, I need to specify that two expressions can occur in any order and in any number between two braces. Below is my code.
所以请准备一个仅包含足够详细信息的问题。)
假设我们从
开始from pyparsing import *
foo = Literal('foo')
bar = Literal('bar')
然后指定"any order and any number between the brackets"
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'], {})