Python re: Me gustaría capturar varias líneas entre un delimitador de cadena

Resuelto Prashanth Iyer asked hace 7 meses • 0 respuestas

Tengo un archivo como este que tiene varias líneas entre un delimitador y quería capturar todo lo que hay entre start_of_compile y end_of_compile excluyendo los comentarios.

cadena que quiero analizar debajo del texto

#####start_of_compile - DO NOT MODIFY THIS LINE#############
##################################################################

parse these lines in between them
...
....

###################################################################
#####end_of_compile -DO NOT MODIFY THIS LINE#################
###################################################################

Quiero ver una coincidencia (.*) para que coincida con varias líneas entre el inicio y el final. Actualmente no es

En lugar de eso veo el siguiente error

def checkcompileqel():
    compiledelimiters = ['start_of_compile_setup']
    with open("compile.qel", "r") as compile_fh:
        lines = compile_fh.read()
        matchstart = re.compile(r'^#+\n#+start.*#+\n#+(.*)#+\n#+end.*#+\n#+',re.MULTILINE)
        print(matchstart.match(lines).group(1))
Traceback (most recent call last):
  File "/process_tools/testcode.py", line 25, in <module>
    print(checkcompileqel())
  File "/home/process_tools/testcode.py", line 10, in checkcompileqel
    print(matchstart.match(lines).group(0))
AttributeError: 'NoneType' object has no attribute 'group'
Prashanth Iyer avatar Feb 16 '24 02:02 Prashanth Iyer
Aceptado

Su expresión regular comienza a intentar hacer coincidir una línea inicial que consta solo de # que no está presente.

Aparte de eso, debe usar re.Sen lugar de re.MULTILINEpara su patrón y hacer que el cuantificador no sea codicioso para no tener una última línea con solo # caracteres.

Si los datos siempre se ven así, no es necesario utilizar el re.Sy un cuantificador no codicioso que evite retrocesos innecesarios.

^#+\n#+start_of_compile\b.*\n#+\n\s*^(.+(?:\n(?!#+$).*)*)

demostración de expresiones regulares

Ejemplo

matchstart = re.compile(
    r'^#+\n#+start_of_compile\b.*\n#+\n\s*^(.+(?:\n(?!#+$).*)*)',
    re.MULTILINE
)
print(matchstart.match(lines).group(1))

Producción

parse these lines in between them
...
....
The fourth bird avatar Feb 15 '2024 19:02 The fourth bird