Сопоставление непустых строк с помощью pyparsing

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

Эти файлы имеют следующий формат.

SOME_KEYWORD:
line 1
line 2
line 3
line 4

ANOTHER_KEYWORD:
line a
line b
line c

Как я могу построить грамматику, которая поможет извлечь line 1, line 2 ... line 4 и line a .. line c? Я пытаюсь сделать такую ​​​​конструкцию

Grammar = Keyword("SOME_KEYWORD:").supress() + NonEmptyLines + EmptyLine.supress() +\
         Keyword("ANOTHER_KEYWORD:").supress() + NonEmptyLines + EmptyLine.supress()

Но я не знаю, как определить NonEmptyLines и EmptyLine. Спасибо.


person Alik    schedule 28.04.2011    source источник


Ответы (2)


Мой взгляд на это:

    from pyparsing import *

    # matches and removes end of line
    EOL = LineEnd().suppress()

    # line starts, anything follows until EOL, fails on blank lines,
    line = LineStart() + SkipTo(LineEnd(), failOn=LineStart()+LineEnd()) + EOL

    lines = OneOrMore(line)

    # Group keyword probably helps grouping these items together, you can remove it
    parser = Keyword("SOME_KEYWORD:") + EOL + Group(lines) + Keyword("ANOTHER_KEYWORD:") + EOL + Group(lines)
    result = parser.parseFile('data.txt')
    print result

Результат:

['SOME_KEYWORD:', ['line 1', 'line 2', 'line 3', 'line 4'], 'ANOTHER_KEYWORD:', ['line a', 'line b', 'line c']]
person Henry    schedule 28.04.2011
comment
+1, хороший ответ. Это приложение довольно линейно-ориентированное, поэтому определение выражения LineEnd() более или менее неизбежно. Обычно, когда вы делаете это, вы также хотите переопределить набор символов пробела по умолчанию, чтобы он не включал \n, используя: ParserElement.setDefaultWhitespaceChars(" \t") сразу после импорта pyparsing. Тогда вы сможете определить LineEnd()*(2,None) как разделитель между группами ключевых слов. - person PaulMcG; 29.04.2011

Это приведет вас к большей части пути:

import pyparsing as pp

data = """
SOME_KEYWORD:
line 1
line 2
line 3
line 4

ANOTHER_KEYWORD:
line a
line b
line c
"""

some_kw = pp.Keyword('SOME_KEYWORD:').suppress()
another_kw = pp.Keyword('ANOTHER_KEYWORD:').suppress()
kw = pp.Optional(some_kw ^ another_kw)

# Hint from: http://pyparsing.wikispaces.com/message/view/home/21931601
lines = kw + pp.SkipTo(
    pp.LineEnd() + pp.OneOrMore(pp.LineEnd()) |
    pp.LineEnd() + pp.StringEnd() |
    pp.StringEnd()
)

result = lines.searchString(data.strip())
results_list = result.asList()
# => [['\nline 1\nline 2\nline 3\nline 4'], ['\nline a\nline b\nline c']]

При построении грамматики действительно помогает назначать части переменным и ссылаться на них, когда это возможно.

person jathanism    schedule 28.04.2011
comment
Pyparsing больше не размещается на wikispaces.com. Перейдите на страницу github.com/pyparsing/pyparsing. - person PaulMcG; 27.08.2018