python、pyparsing、stopOn 和重复结构

python, pyparsing, stopOn and repeating structures

是时候重温我的 pyparsing 技能了。

给定一个包含重复结构的文件

space_missions
Main Objects:
  /Projects/antares_III
  /Projects/apollo
ground_missions
Main Objects:
  /Projects/Barbarossa
  /Projects/Desert_Eagle

和我砍掉的 2.7 脚本

def last_occurance_of( expr):
  return expr + ~pp.FollowedBy( expr)

ppKeyName = pp.Word( pp.alphanums)
ppObjectLabel = pp.Literal("Main Objects") + pp.FollowedBy(':')
ppObjectRegex = pp.Regex(r'\/Projects\/\w+')
ppTag = pp.Group( ppKeyName.setResultName('keyy') + pp.Suppress( ppObjectLabel) + pp.ZeroOrMore( ppObjectRegex, stopOn=last_occurance_of( ppObjectRegex)).setResultName('objects') )
ppTags = pp.OneOrMore( ppTag)
with open( fn) as fp:
  slurp = fp.read()
results = ppTags.parseString( slurp)

我想将结果发送到 return

[['space_missions',['/Projects/antares_III','/Projects/apollo']
,['ground_missions',['/Projects/Barbarossa','/Projects/Desert_Eagle']]

那么我在这里缺少什么?我意识到我很幸运,因为构成列表的字符串都有相同的开头,这让 last_occurance_of() 有一些东西可以锁定,但是在更一般的情况下,字符串什么都没有将它们与标签字符串区分开来

仍在寻找史蒂夫

解析器中需要修复的三件事:

  1. 您给定的 ppKeyNames 包含“_”,但您没有将它们包含在 ppKeyName

  2. 的定义中
  3. ppObjectLabel 将解析 "Main Objects" 后跟一个 ':',但 ':' 实际上不会在任何地方被解析。最简单的方法是将它添加到 ppObjectLabel 而不是使用 pp.FollowedBy.

  4. last_occurance_of是不必要的,ppObjectRegex的重复不会被下一个标签的ppKeyName

  5. 混淆