Acceda a elementos analizados utilizando Pyparsing

Tengo un montón de oraciones que necesito analizar y convertir al código de búsqueda de expresiones regulares correspondiente. Ejemplos de mis oraciones -

LINE_CONTAINS phrase one BEFORE {phrase2 AND phrase3} AND LINE_STARTSWITH Therefore we

-Esto significa en la línea,phrase one viene a alguna parte antesphrase2 yphrase3. Además, la línea debe comenzar conTherefore we

LINE_CONTAINS abc {upto 4 words} xyz {upto 3 words} pqr

-Esto significa que necesito permitir hasta 4 palabras entre las primeras 2 frases y hasta 3 palabras entre las últimas 2 frases

Usando la ayuda de Paul Mcguire (aquí), se escribió la siguiente gramática:

from pyparsing import (CaselessKeyword, Word, alphanums, nums, MatchFirst, quotedString, 
    infixNotation, Combine, opAssoc, Suppress, pyparsing_common, Group, OneOrMore, ZeroOrMore)

LINE_CONTAINS, LINE_STARTSWITH = map(CaselessKeyword,
    """LINE_CONTAINS LINE_STARTSWITH """.split()) 

NOT, AND, OR = map(CaselessKeyword, "NOT AND OR".split())
BEFORE, AFTER, JOIN = map(CaselessKeyword, "BEFORE AFTER JOIN".split())

lpar=Suppress('{') 
rpar=Suppress('}')

keyword = MatchFirst([LINE_CONTAINS, LINE_STARTSWITH, LINE_ENDSWITH, NOT, AND, OR, 
                      BEFORE, AFTER, JOIN]) # declaring all keywords and assigning order for all further use

phrase_word = ~keyword + (Word(alphanums + '_'))

upto_N_words = Group(lpar + 'upto' + pyparsing_common.integer('numberofwords') + 'words' + rpar)

phrase_term = Group(OneOrMore(phrase_word) + ZeroOrMore((upto_N_words) + OneOrMore(phrase_word))  



phrase_expr = infixNotation(phrase_term,
                            [
                             ((BEFORE | AFTER | JOIN), 2, opAssoc.LEFT,), # (opExpr, numTerms, rightLeftAssoc, parseAction)
                             (NOT, 1, opAssoc.RIGHT,),
                             (AND, 2, opAssoc.LEFT,),
                             (OR, 2, opAssoc.LEFT),
                            ],
                            lpar=Suppress('{'), rpar=Suppress('}')
                            ) # structure of a single phrase with its operators

line_term = Group((LINE_CONTAINS | LINE_STARTSWITH | LINE_ENDSWITH)("line_directive") + 
                  Group(phrase_expr)("phrase")) # basically giving structure to a single sub-rule having line-term and phrase
line_contents_expr = infixNotation(line_term,
                                   [(NOT, 1, opAssoc.RIGHT,),
                                    (AND, 2, opAssoc.LEFT,),
                                    (OR, 2, opAssoc.LEFT),
                                    ]
                                   ) # grammar for the entire rule/sentence

sample1 = """
LINE_CONTAINS phrase one BEFORE {phrase2 AND phrase3} AND LINE_STARTSWITH Therefore we
"""
sample2 = """
LINE_CONTAINS abcd {upto 4 words} xyzw {upto 3 words} pqrs BEFORE something else
"""

Mi pregunta ahora es: ¿cómo accedo a los elementos analizados para convertir las oraciones a mi código regex? Para esto, probé lo siguiente:

parsed = line_contents_expr.parseString(sample1)/(sample2)
print (parsed[0].asDict())
print (parsed)
pprint.pprint(parsed)

El resultado del código anterior parasample1 estaba -

{}

[[['LINE_CONTAINS', [[['' oración ',' uno '],' ANTES ', [[' oración2 '],' AND ', [' oración3 ']]]]],' AND ', [' LINE_STARTSWITH ', [[' 'Por lo tanto', 'nosotros']]]]]

([([(['LINE_CONTAINS', ([([([oración ',' uno '], {}),' ANTES ', ([([' oración2 '], {}),' Y ', (['oración3'], {})], {})], {})], {})], {'frase': [(([([([' oración ',' uno '], {}),' ANTES ', ([([' oración2 '], {}),' AND ', ([' oración3 '] , {})], {})], {})], {}), 1)], 'line_directive': [(' LINE_CONTAINS ', 0)]}),' AND ', ([' LINE_STARTSWITH ', ([(' 'Por lo tanto,' nosotros '], {})], {})], {'frase': [(([([' 'Por lo tanto,' nosotros '], {})], {}), 1)],'line_directive': [(' LINE_STARTSWITH ', 0)]})], {})], {})

El resultado del código anterior parasample2 estaba -

{'frase': [[['a B C D', {'número de palabras': 4},' xyzw ', {'número de palabras': 3},' pqrs '],' ANTES ', [' algo ',' más ']]],'line_directive':' LINE_CONTAINS '}

[['LINE_CONTAINS', [[['' abcd ', [' upto ', 4,' palabras '],' xyzw ', [' upto ', 3,' palabras '],' pqrs '],' ANTES ', ['algo más']]]]]

([(['' LINE_CONTAINS ', ([([([' abcd ', ([' upto ', 4,' palabras '], {'número de palabras': [(4, 1)]}),' xyzw ', ([' 'hasta', 3, 'palabras'], {'número de palabras': [(3, 1)]}),' pqrs '], {}),' ANTES ', ([' algo ',' más '], {})], {})], {})] , {'frase': [(([([(['' abcd ', ([' 'hasta', 4, 'palabras'], {'número de palabras': [(4, 1)]}),' xyzw ', ([' 'hasta', 3, 'palabras'], {'número de palabras': [(3, 1)]}), 'pqrs'], { }), 'ANTES', (['algo', 'más'], {})], {})], {}), 1)], 'line_directive': [(' LINE_CONTAINS ', 0)]})], {})

Mis preguntas basadas en el resultado anterior son:

¿Por qué el pprint (impresión bonita) tiene un análisis más detallado que la impresión normal?¿Por qué elasDict() método no da salida parasample1 pero lo hace porsample2?Cada vez que intento acceder a los elementos analizados usandoprint (parsed.numberofwords) oparsed.line_directive oparsed.line_termNo me da nada. ¿Cómo puedo acceder a estos elementos para usarlos para construir mis códigos regex?

Respuestas a la pregunta(1)

Su respuesta a la pregunta