scanf en python
Chema Cortés
ch3m4 en ch3m4.org
Mar Sep 30 18:53:38 CEST 2003
Hola,
Estaba buscando algún método para fragmentar líneas de texto en campos
de datos para su proceso. El formato de línea de los ficheros que
utilizo puede variar bastante a menudo, así que quería algo que fuera
simple de mantener en el futuro.
Como primera opción pensé en el rebanado de cadenas; pero buscando
alguna optimización encontré el ejemplo que hay en la documentación del
módulo re que simula el scanf. Lo he mejorado utilizando grupos de
búsqueda (pongo el código abajo).
Antes de seguir, me preguntaba, por ser ésta una tarea bastante
habitual, si alguien sabe de alguna solución elegante al problema.
Pongo el código en el que estoy trabajando (no está terminado).
Convierte un fichero de campos de tamaño fijo en otro de campos
delimitados por el carácter '|':
(-------- principio del fichero ------------)
#!/usr/bin/python
# -*- coding: iso8859-15 -*-
import sys
import re
from datetime import date
fIn=file("nmcl0703.txt","r")
fOut=file("nmcl0703.txt"+".out","w")
#establezco el formato de línea del fichero de entrada
#(nombre_del_campo, longitud, tipo)
incommingRecord=(
("especialidad",6,int),
("",2,None), #gap
("laboratorio",3,int),
("estado",2,str),
("grupo",5,str),
("",4,None), #gap
("precio",8,float),
("",8,None), #gap
("precio1",8,None),
("precio2",8,None),
("precio3",8,None),
("precio4",8,None),
("precio5",8,None),
("precio6",8,None),
("precio7",8,None),
("precio8",8,None),
("tipoaportacion",1,int),
("",4,None), #gap
("nombrecomercial",42,str),
("",8,None), #gap
("casacomercial",42,str)
)
outcommingRecord=[k for (k,n,t) in incommingRecord if t ]
#creo la expresión regular
#utilizo grupos de búsqueda con nombre (?P<nombre>pattern)
s=""
for k,n,t in incommingRecord:
if k:
s+="(?P<%s>.{%d})"%(k,n)
else:
s+=".{%d}"%n
s+="(?P<RESTO>.*)"
mk=re.compile(s)
for l in fIn:
#generamos un diccionario con los campos
r=mk.search(l).groupdict()
#cambio de tipos
for nom,tipo in [ (k,t) for (k,n,t) in incommingRecord if t in
(int,float) ]:
r[nom]=tipo(r[nom])
#combinamos campos para la salida
res="|".join([ str(r[k]) for k in outcommingRecord ])
print >>fOut, res+"|"
#(------ fin del fichero ------)
--
Res publica non dominetur
Más información sobre la lista de distribución Python-es