【问题标题】:Parsing data between multiple brackets and different kind of brackets在多个括号和不同类型的括号之间解析数据
【发布时间】:2015-05-04 22:58:14
【问题描述】:

我正在尝试解析位于三种类型括号内的数据。 {}、[] 和

棘手的部分是数据可以嵌套在多个括号之间。

简单案例:

element-type { a | b | c | d} [ duration ]

这是一个简单的案例,我可以使用正则表达式来抓取 {} 和 [] 之间的内容

这是一个更难的例子

tcp [ udp-mode { off | on { encrypted | plain }}]

我在这里基本上想做的是提取“udp-mode”,然后提取可能的选项和选项选项。我打算将其存储在树结构中。我正在努力弄清楚如何解析这个?棘手的部分是嵌套 {},因为它可以嵌套得更远。

  • [] = 可选
  • {} = 从以下选项中选择一个
  • = 用户输入

如果是大括号,我想抓住大括号之前的所有内容,直到我碰到另一个右括号或字符串的开头。

对于方括号,我想抓取其中的所有内容。但同样,它们可以包含大括号或

对于 我想抓住里面的所有东西,以及之前的所有东西,直到碰到括号或字符串的开头

解析这类数据的好方法是什么?

【问题讨论】:

  • 这些数据从何而来?
  • tcp [ udp-mode { off | on { encrypted | plain }}] 的期望输出是什么?
  • 最终目标是这样的。 Upd-mode 是字典中的一个键。然后它将包含一个列表,该列表具有关闭、打开和打开状态,而另一个列表包含加密的、普通的。或者像这样的树形结构

标签: python regex parsing


【解决方案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']]]]]]]]]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多