Encuentra coincidencias más cortas entre dos cadenas
Tengo un archivo de registro grande y quiero extraer una cadena de varias líneas entre dos cadenas: start
y end
.
La siguiente es una muestra de inputfile
:
start spam
start rubbish
start wait for it...
profit!
here end
start garbage
start second match
win. end
La solución deseada debería imprimir:
start wait for it...
profit!
here end
start second match
win. end
Probé una expresión regular simple pero devolvió todo desde start spam
. ¿Cómo debe hacerse esto?
Editar: información adicional sobre la complejidad computacional de la vida real :
- tamaño real del archivo: 2 GB
- apariciones de 'inicio': ~ 12 M, distribuidas uniformemente
- apariciones de 'fin': ~800, cerca del final del archivo.
Aceptado
Esta expresión regular debe coincidir con lo que desea:
(start((?!start).)*?end)
Utilice re.findall
el método y el modificador de una sola línea re.S
para obtener todas las apariciones en una cadena de varias líneas:
re.findall('(start((?!start).)*?end)', text, re.S)
Vea una prueba aquí .
Hazlo con código - máquina de estados básica:
open = False
tmp = []
for ln in fi:
if 'start' in ln:
if open:
tmp = []
else:
open = True
if open:
tmp.append(ln)
if 'end' in ln:
open = False
for x in tmp:
print x
tmp = []