2010-01-26 38 views
5

Una línea CSV trivial podría ser escupido usando función de cadena de división. Pero algunas líneas podría tener ", por ejemploCómo leer una línea CSV con "?

"good,morning", 100, 300, "1998,5,3" 

así directamente usando dividida cadena no resolvería el problema.

Mi solución es dividir primero en salir de la línea usando , y luego combinando las cuerdas con " a continuación, comenzar o al final de la cadena.

¿Cuál es la mejor práctica para este problema?

Me interesa saber si hay un fragmento de código de Python o F # para esto.

EDIT: Estoy más interesado en los detalles de implementación, en lugar de utilizar una biblioteca.

Respuesta

9

Hay un módulo csv en Python, que maneja esto.

Editar: Esta tarea se encuentra en la categoría "crear un lexer". La forma estándar de hacer este tipo de tareas es la construcción de una máquina de estados

la máquina de estado para esta tarea sería probablemente sólo necesitará dos estados (o utilizar una biblioteca lexer/marco que lo haga por usted.):

  • Inicial, donde lee todos los caracteres excepto coma y nueva línea como parte del campo (excepción: espacios iniciales y finales), coma como el separador de campo, nueva línea como separador de registros. Cuando encuentra una cotización de apertura entra en
  • estado de campo de cotización de lectura, donde cada carácter (incluida la coma & línea nueva) sin incluir la cotización se trata como parte del campo, una cotización que no sigue una cotización significa final de cotizada -field (volver al estado inicial), una cita seguida de una cita se trata como una sola cita (cita escapada).

Por cierto, su solución concatenante se romperá en "Field1","Field2" o "Field1"",""Field2".

+5

Al igual que con la mayoría de los problemas de análisis, es una práctica más sostenible a utilizar una biblioteca, si existiera. Si el OP está realmente interesado en la implementación, estoy seguro de que la biblioteca de Python es de código abierto. –

+3

Como decimos en la comunidad de Python: "Usa la fuente, Luke". Está totalmente abierto y ya está instalado con Python. Solo leelo. –

3

De python's CSV module:

la lectura de un archivo CSV normales:

import csv 
reader = csv.reader(open("some.csv", "rb")) 
for row in reader: 
    print row 

La lectura de un archivo con un formato alternativo:

import csv 
reader = csv.reader(open("passwd", "rb"), delimiter=':', quoting=csv.QUOTE_NONE) 
for row in reader: 
    print row 

hay algunas nice usage examples in LinuxJournal.com.

Si le interesan los detalles, lea "split string at commas respecting quotes when string not in csv format" que muestra algunas expresiones correctas relacionadas con este problema, o simplemente lea la fuente del módulo csv.

1

El Capítulo 4 de La práctica de la programación dio implementaciones C y C++ del analizador CSV.

1

El detalle de implementación genérica sería algo como esto (no probado)

def csvline2fields(line): 
    fields = [] 
    quote = None 
    while line.strip(): 
     line = line.strip() 
     if line[0] in ("'", '"'): 
      # Find the next quote: 
      end = line.find(line[0]) 
      fields.append(line[1:end]) 
      # Find the beginning of the next field 
      next = line.find(SEPARATOR) 
      if next == -1: 
       break 
      line = line[next+1:] 
      continue 
     # find the next separator: 
     next = line.find(SEPARATOR) 
     fields.append(line[0:next]) 
     line = line[next+1:] 
+0

En realidad, la recomendación de mirar el módulo CSV en la fuente abierta de Python es mucho mejor. Tonto de mí. –

Cuestiones relacionadas