2011-01-04 6 views
5

Soy un aficionado que usa Python de forma intermitente desde hace algún tiempo. Lo siento si esto es una pregunta tonta, pero me preguntaba si alguien sabía una manera fácil de agarrar un montón de líneas si el formato del archivo de entrada es de esta manera:Cómo agarrar las líneas DESPUÉS de una línea coincidente en python

" Título 1

Línea 1

Line 2

Línea 3

Heading 2

Line 1

Línea 2

Línea 3 "

yo no sé cuántas líneas están después de cada título, pero quiero agarrar a todos. Todo lo que sé es el nombre, o un patrón de expresión regular para el encabezado.

La única forma que conozco de leer un archivo es la forma "for line in file:", pero no sé cómo tomar las líneas DESPUÉS de la línea en la que estoy actualmente. Espero que esto tenga sentido, ¡y gracias por la ayuda!

* ¡Gracias por todas las respuestas! He tratado de implementar algunas de las soluciones, pero mi problema es que no todos los títulos tienen el mismo nombre, y no estoy seguro de cómo solucionarlo. Necesito una expresión regular diferente para cada ... alguna sugerencia? *

+0

En respuesta a su edición: necesita tener una manera de identificar qué líneas son encabezados. ¿Puedes darnos algunos ejemplos reales? –

+0

Claro, aquí hay algunas expresiones regulares que estoy usando para identificar encabezados, delimitados por //: '[0-9] + elementos comunes:' // '[0-9] + modelos con elementos [0-9]: '//' Modelo model_ [0-9] el_ [0-9] ' – toofly

+0

No confunda este problema (encabezado y detalles) con un segundo problema, y ​​solo parcialmente relacionado. No actualice esto para agregar confusión. Primero: busque SO para obtener ayuda con la expresión regular. Segundo: Buscar tutoriales de Python para obtener ayuda con la expresión regular. Tercero: después de probar el código que no funciona, crea una ** nueva ** pregunta centrada únicamente en tu problema de expresión regular. Con código. Eso no funciona. –

Respuesta

7

Generador Funciones

def group_by_heading(some_source): 
    buffer= [] 
    for line in some_source: 
     if line.startswith("Heading"): 
      if buffer: yield buffer 
      buffer= [ line ] 
     else: 
      buffer.append(line) 
    yield buffer 

with open("some_file", "r") as source: 
    for heading_and_lines in group_by_heading(source): 
     heading= heading_and_lines[0] 
     lines= heading_and_lines[1:] 
     # process away. 
+0

+1, pero creo que quiere decir 'buffer = [línea]' en lugar de 'buffer = [encabezado]'. –

+0

¡Gracias! Esta es una gran solución (tuvo que leer un poco sobre las funciones del generador). – toofly

+0

@toofly: si acepta la respuesta de S.Lott, ambos obtendrán puntos de reputación. –

0

Realmente no sé Python, pero aquí hay un poco de pseudocódigo.

int header_found = 0;

[START en bucle en el que está recorriendo las líneas de archivo]

si (header_found == 1) [línea de arrastre]; header_found = 0;

if (línea = ~/[regexp para el encabezado] /) header_found = 1;

La idea es tener una variable que haga un seguimiento de si ha encontrado un encabezado o no, y si lo tiene, para tomar la siguiente línea.

4

Se puede usar una variable para marcar dónde qué partida está realizando el seguimiento en la actualidad, y si se establece, agarrar cada línea hasta que encuentre otra partida:

data = {} 
for line in file: 
    line = line.strip() 
    if not line: continue 

    if line.startswith('Heading '): 
     if line not in data: data[line] = [] 
     heading = line 
     continue 

    data[heading].append(line) 

He aquí un fragmento http://codepad.org que muestra cómo funciona : http://codepad.org/KA8zGS9E

Editar: Si no se preocupan por los valores de rumbo real y sólo quiere una lista al final, puede utilizar esto:

data = [] 
for line in file: 
    line = line.strip() 
    if not line: continue 

    if line.startswith('Heading '): 
     continue 

    data.append(line) 

Básicamente, realmente no necesita rastrear una variable para el encabezado, en su lugar puede filtrar todas las líneas que coinciden con el patrón de Encabezado.

1

Aparte de un generador, creo que podemos crear un dict donde la clave es "Encabezado" y el valor es una lista para guardar las líneas. Aquí está el código

odd_map = {} 
odd_list = [] 
with open(file, 'r') as myFile: 
    lines = myFile.readlines() 
    for line in lines: 
     if "Heading" in line: 
      odd_list = [] 
      odd_map[line.strip()] = odd_list 
     else:  
      odd_list.append(line.strip()) 

for company, odds in odd_map.items(): 
    print(company) 
    for odd in odds: 
     print(odd) 
Cuestiones relacionadas