我正在使用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))
但它没有用。我得到的是错误或解析器将所有数据作为一条记录吞噬。
答案 0 :(得分:1)
您使用~FollowedBy
走在正确的轨道上,但这些表达式必须是OneOrMore
重复表达式的一部分。类似的东西:
multilineString = Group(token + equals + OneOrMore(stringTemplate + ~FollowedBy(equals)))
for match in multilineString.searchString(test):
match.pprint()
其他一些评论:
token
,decimal
和stringTemplate
的定义。就目前而言,您永远不会匹配decimal
表达式。为避免误导integer
token
,我建议您将token
更改为Word(alphas, alphanums + "-,./_:*+=#[];")
token
的一部分。如果有人忽略了token
和分隔' ='之间的空格,那么分隔符的内容将会被提升到token
键。multilineString = Group(token("key") + equals + OneOrMore(stringTemplate + ~FollowedBy(equals))("value"))
。然后你可以像match.key
和match.value
那样访问它们 - 当然你可以使用列表索引来获取密钥match[0]
,但我发现命名访问更容易使用。