2008-09-22 9 views

Respuesta

24

La solución del módulo shlex permite cotizaciones escapadas, una cotización escapa a otra y todas las cosas sofisticadas admiten shell.

>>> import shlex 
>>> my_splitter = shlex.shlex('''foo, bar, "one, two", three four''', posix=True) 
>>> my_splitter.whitespace += ',' 
>>> my_splitter.whitespace_split = True 
>>> print list(my_splitter) 
['foo', 'bar', 'one, two', 'three', 'four'] 

escaparon cotizaciones ejemplo:

>>> my_splitter = shlex.shlex('''"test, a",'foo,bar",baz',bar \xc3\xa4 baz''', 
           posix=True) 
>>> my_splitter.whitespace = ',' ; my_splitter.whitespace_split = True 
>>> print list(my_splitter) 
['test, a', 'foo,bar",baz', 'bar \xc3\xa4 baz'] 
+1

Esto divide el tres y cuatro, que no está en la especificación. –

+0

Necesita una solución para dividir el "tres cuatro" final. – tzot

+3

Simplemente cambiando my_splitter.whitespace + = ',' to = ',' lo hará, pero aún necesita quitar cada elemento. –

5

Quizás también desee considerar el módulo csv. No lo he intentado, pero parece que tus datos de entrada están más cerca del CSV que de la sintaxis del shell (que es lo que analiza el shlex).

+0

De acuerdo. Menos las porciones '' 'adjuntas, que se parece al formato CSV bastante estándar. (Bueno, tanto como pueda, sin un estándar de CSV.) – jdmichal

+0

@jdmichal: El '' 'es solo una forma de comillas cadenas en Python. – tzot

1

Se podría hacer algo como esto:

>>> import re 
>>> pattern = re.compile(r'\s*("[^"]*"|.*?)\s*,') 
>>> def split(line): 
... return [x[1:-1] if x[:1] == x[-1:] == '"' else x 
...   for x in pattern.findall(line.rstrip(',') + ',')] 
... 
>>> split("foo, bar, baz") 
['foo', 'bar', 'baz'] 
>>> split('foo, bar, baz, "blub blah"') 
['foo', 'bar', 'baz', 'blub blah'] 
-2

Si no tiene que ser bonita, esto podría obtener en su camino:

def f(s, splitifeven): 
    if splitifeven & 1: 
     return [s] 
    return [x.strip() for x in s.split(",") if x.strip() != ''] 

ss = 'foo, bar, "one, two", three four' 

print sum([f(s, sie) for sie, s in enumerate(ss.split('"'))], []) 
39

Depende de lo complicado que desea obtener ... ¿desea permitir más de un tipo de cotización. ¿Qué hay de las frases escapadas?

Su sintaxis se parece mucho al formato de archivo CSV común, que es apoyado por la biblioteca estándar de Python:

import csv 
reader = csv.reader(['''foo, bar, "one, two", three four'''], skipinitialspace=True) 
for r in reader: 
    print r 

Salidas:

['foo', 'bar', 'one, two', 'three four'] 

HTH!

+1

Sí, el módulo csv es totalmente lo que quieres aquí. –

+3

Acabo de probar esto y funciona como un regalo. Una sintaxis más directa que el módulo shlex, ¡así que esto obtiene mi voto! – DaGaMs

+0

buena solución simple upvoted. – PythonTester

0

yo diría que una expresión regular sería lo que estás buscando aquí, aunque no estoy terriblemente familiar con motor de expresiones regulares de Python.

Suponiendo que usa coincidencias flojas, puede obtener un conjunto de coincidencias en una cadena que puede colocar en su matriz.

Cuestiones relacionadas