python, pyparsing, stopOn и повторяющиеся структуры - PullRequest
0 голосов
/ 10 февраля 2019

Пришло время освежить мои навыки разбора.

, учитывая файл, содержащий повторяющиеся структуры

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)

Я бы хотел получить результаты для возврата

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

Так чего мне здесь не хватает?Я понимаю, что мне повезло в том, что строки, составляющие списки, имеют одинаковое начало, которое дает last_occurance_of () что-то, к чему можно привязываться, но что нужно делать в более общем случае, когда строки не имеют ничего, чтобы отличить их отtag-strings

Все еще ищущий Стив

1 Ответ

0 голосов
/ 10 февраля 2019

Три вещи, которые нужно исправить в вашем парсере:

  1. Ваши заданные ppKeyNames включают '_'s, но вы не включаете их в определение ppKeyName

  2. ppObjectLabel будет анализировать «Основные объекты», за которыми следует «:», но «:» фактически нигде не анализируется.Проще всего добавить его в ppObjectLabel вместо использования pp.FollowedBy.

  3. last_occurance_of не требуется, повторение ppObjectRegex не будет смущено следующим тегом ppKeyName

...