这是你的问题,使用 pyparsing:
from pyparsing import *
LBRACK,RBRACK,LBRACE,RBRACE,LANGLE,RANGLE,VERT_BAR = map(Suppress,"[]{}<>|")
expr = Forward()
ident = Word(alphas, alphanums+'-_')
optional_expr = (LBRACK + expr + RBRACK)
reqd_expr = (LBRACE + expr + RBRACE)
user_expr = (LANGLE + OneOrMore(ident) + RANGLE)
term = ident | optional_expr | reqd_expr | user_expr
term = Group(term * (2,None)) | term
expr <<= OneOrMore(term + ~VERT_BAR | Group(delimitedList(term,VERT_BAR)))
tests = """\
element-type { a | b | c | d} [ duration ]
tcp [ udp-mode { off | on { encrypted | plain }}]""".splitlines()
for t in tests:
print t
print expr.parseString(t).asList()[0]
print
打印:
element-type { a | b | c | d} [ duration ]
['element-type', ['a', 'b', 'c', 'd'], 'duration']
tcp [ udp-mode { off | on { encrypted | plain }}]
['tcp', ['udp-mode', ['off', ['on', ['encrypted', 'plain']]]]]
为了查看如何解释不同的分组,我添加了解析时操作来装饰返回的组:
def make_pa(prefix):
def pa(tokens):
return ParseResults([prefix] + [tokens])
return pa
optional_expr = (LBRACK + expr + RBRACK).setParseAction(make_pa("OPT:"))
reqd_expr = (LBRACE + expr + RBRACE).setParseAction(make_pa("REQD:"))
user_expr = (LANGLE + OneOrMore(ident) + RANGLE).setParseAction(make_pa("USER:"))
term = ident | optional_expr | reqd_expr | user_expr
term = Group(term * (2,None)) | term
alternation = Group(term + OneOrMore(VERT_BAR + term))
alternation.setParseAction(make_pa("OR:"))
您的两个测试字符串返回以下嵌套列表:
element-type { a | b | c | d} [ duration ]
['element-type', 'REQD:', ['OR:', [['a', 'b', 'c', 'd']]], 'OPT:', ['duration']]
tcp [ udp-mode { off | on { encrypted | plain }}]
['tcp', 'OPT:', [['udp-mode', 'REQD:', ['OR:', [['off', ['on', 'REQD:', ['OR:', [['encrypted', 'plain']]]]]]]]]]