pyparsing захват групп произвольного текста с заданными заголовками в виде вложенных списков

У меня есть текстовый файл, похожий на;

заголовок раздела 1:
некоторые слова могут быть чем угодно
больше слов может быть что угодно вообще
и т.д. и т.д. лала

другой заголовок:
как раньше могло быть что угодно
эй это не весело

Я пытаюсь составить грамматику с pyparser, которая приведет к следующей структуре списка при запросе проанализированных результатов в виде списка; (IE, при повторении через элементы parsed.asList () следует печатать следующее:

['header 1:', [['some words can any anything]], [' больше слов может быть что угодно вообще], ['etc etc lala']]]
['some other header:', [['как раньше может быть что угодно "], [' hey is not this fun ']]]

Имена заголовков известны заранее, и отдельные заголовки могут отображаться или не отображаться. Если они появляются, то всегда есть хотя бы одна строка контента.

Проблема, с которой я столкнулась, заключается в том, что у меня возникла проблема с gettnig парсером, чтобы узнать, где начинается «заголовок раздела 1:» и «и другой заголовок:». В итоге я выгляжу как parsed.asList ();

['header 1:', [['' некоторые слова могут быть любыми '], [' больше слов может быть вообще что угодно], ['etc etc lala'], ['some other header'], [' «как раньше мог быть что угодно»], ['hey is not this fun']]]

(IE: заголовок раздела 1: отображается правильно, но каждый последующий за ним добавляется в заголовок раздела 1, включая другие строки заголовков и т. Д.).

Ive пробовал различные вещи, играл с leaveWhitespace () и LineEnd () различными способами, но я не могу понять это.

Базовый анализатор, с которым я разбираюсь, – это (надуманный пример – на самом деле это определение класса и т. Д.).

header_1_line=Literal('section header 1:') text_line=Group(OneOrMore(Word(printables))) header_1_block=Group(header_1_line+Group(OneOrMore(text_line))) header_2_line=Literal('some other header:') header_2_block=Group(header_2_line+Group(OneOrMore(text_line))) overall_structure=ZeroOrMore(header_1_block|header_2_block) 

и вызывается с

 parsed=overall_structure.parseFile() 

Приветствия, Мэтт.

One Solution collect form web for “pyparsing захват групп произвольного текста с заданными заголовками в виде вложенных списков”

Мэтт –

Добро пожаловать в pyparsing! Вы попали в одну из самых распространенных ошибок в работе с pyparsing, и это то, что люди умнее компьютеров. Когда вы смотрите на текст ввода, вы можете легко увидеть, какой текст может быть заголовком, а какой текст не может быть. К сожалению, pyparsing не так интуитивно, поэтому вы должны прямо сказать, что может и не может быть текстом.

Когда вы смотрите на свой образец текста, вы не принимаете какую-либо строку текста как возможный текст в заголовке раздела. Откуда вы знаете, что «другой заголовок:» недействителен как текст? Поскольку вы знаете, что эта строка соответствует одной из известных строк заголовков. Но в вашем текущем коде вы сказали, что любая коллекция Word(printables) является допустимым текстом, даже если эта коллекция является допустимым заголовком раздела .

Чтобы исправить это, вам нужно добавить явный взгляд на ваш парсер. Pyparsing предлагает две конструкции: NotAny и FollowedBy. NotAny может быть сокращен с помощью оператора ~ ~, поэтому мы можем написать это выражение псевдокода для текста:

 text = ~any_section_header + everything_up_to_the_end_of_the_line 

Вот полный синтаксический анализатор, использующий негативный взгляд, чтобы убедиться, что вы читаете каждый раздел, разбивая заголовки разделов:

 from pyparsing import ParserElement, LineEnd, Literal, restOfLine, ZeroOrMore, Group, StringEnd test = """ section header 1: some words can be anything more words could be anything at all etc etc lala some other header: as before could be anything hey isnt this fun """ ParserElement.defaultWhitespaceChars=(" \t") NL = LineEnd().suppress() END = StringEnd() header_1=Literal('section header 1:') header_2=Literal('some other header:') any_header = (header_1 | header_2) # text isn't just anything! don't accept header line, and stop at the end of the input string text=Group(~any_header + ~END + restOfLine) overall_structure = ZeroOrMore(Group(any_header + Group(ZeroOrMore(text)))) overall_structure.ignore(NL) from pprint import pprint print(overall_structure.parseString(test).asList()) 

В моей первой попытке я забыл также искать конец строки, поэтому выражение restOfLine зацикливается навсегда. Добавив второй заголовок для конца строки, моя программа успешно завершается. Упражнение осталось для вас: вместо перечисления всех возможных заголовков определите строку заголовка как любую строку, которая заканчивается символом ':'.

Удачи вам в ваших усилиях, связанных с пиратством, – Пол

  • Войдите в Facebook, используя запросы python
  • Как рисовать элементы из нескольких списков для создания несопровождаемого?
  • Как декодировать сохраненные файлы журналов из App Engine Python Dev_server
  • Исключение Python / ValueError / Обработка ошибок
  • Как перечислить импортированные модули?
  • Python номера игра обратная
  • Неожиданное значение функции floor () в python
  • Google App Engine: как отправить html с помощью send_mail
  • Python - лучший язык программирования в мире.