我正在尝试解析位于三种括号内的数据。 {},[]和<>
棘手的部分是数据可以嵌套在多个括号之间。
简单案例:
element-type { a | b | c | d} [ duration ]
这是一个简单的案例,我可以使用正则表达式来抓取{}和[]
之间的东西这是一个更难的例子
tcp [ udp-mode { off | on { encrypted | plain }}]
我本来想要做的是提取“udp-mode”,然后提取可能的选项和选项选项。我打算将它存储在树形结构中。我正在努力弄清楚如何解析这个?棘手的部分是嵌套{},因为它可以进一步嵌套。
如果它的花括号我想要在大括号之前抓住所有内容,直到我点击另一个右括号或字符串的开头。
对于方括号,我想抓住它里面的一切。但同样,它们可以包含大括号或<>
对于<>我想要抓住里面的一切,以及之前的所有内容,直到命中一个括号或字符串
解析此类数据的好方法是什么?
答案 0 :(得分:1)
以下是使用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']]]]]]]]]]