如何解析没有分隔符的元组?

时间:2016-07-06 11:50:54

标签: python python-3.x parsing pyparsing

我正在使用pyparser,并且想要解析包含树结构的文件,其值在等号后面存储,否则没有实际的分隔符。

我已经完成了所有的解析,除了极少数情况下数据存储在多行中,所以我必须重写解析器不要停止抓取值从等号到行尾但是从等号到另一行等号(或end)忽略前面的单词(或忽略end)。

数据示例:

(
  ItemName = foo
  SomeOtherStuff = bar
  foo1
  foo2
  AString1 = ItemName
  SomeOtherStuff 
)

代码:

equals = Suppress("=")
token = Word(alphanums + "-,./_:*+=#[];")
decimal = Regex(r'-?0|[1-9]\d*').setParseAction(lambda t:int(t[0]))
stringTemplate = token | decimal
sexpList = Group(Suppress("(") + ZeroOrMore(sexp) + Suppress(")")) 
sexp = Forward()

这显然不起作用

  

astring = Group(stringTemplate + equals + stringTemplate)

所以我试过这些:

multilineString = Group(token + equals + OneOrMore(stringTemplate) + ~FollowedBy(stringTemplate + equals))
multilineString = Group(token + equals + OneOrMore(stringTemplate) + NotAny(stringTemplate + equals))
multilineString = Group(token + equals + OneOrMore(stringTemplate) + ~(stringTemplate + equals))

但它没有用。我得到的是错误或解析器将所有数据作为一条记录吞噬。

1 个答案:

答案 0 :(得分:1)

您使用~FollowedBy走在正确的轨道上,但这些表达式必须是OneOrMore重复表达式的一部分。类似的东西:

multilineString = Group(token + equals + OneOrMore(stringTemplate + ~FollowedBy(equals)))
for match in multilineString.searchString(test):
    match.pprint()

其他一些评论:

  • 查看tokendecimalstringTemplate的定义。就目前而言,您永远不会匹配decimal表达式。为避免误导integer token,我建议您将token更改为Word(alphas, alphanums + "-,./_:*+=#[];")
  • 您可能想重新考虑是否要允许' ='作为token的一部分。如果有人忽略了token和分隔' ='之间的空格,那么分隔符的内容将会被提升到token键。
  • 考虑添加结果名称,以帮助您访问每个键值对的键和值位:multilineString = Group(token("key") + equals + OneOrMore(stringTemplate + ~FollowedBy(equals))("value"))。然后你可以像match.keymatch.value那样访问它们 - 当然你可以使用列表索引来获取密钥match[0],但我发现命名访问更容易使用。