Domanda

Devo essere in grado di prendere una stringa come:

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

in:

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

Ho la sensazione (con i suggerimenti di #python) che la soluzione coinvolgerà il modulo shlex.

È stato utile?

Soluzione

La soluzione del modulo shlex consente le virgolette sfuggite, una virgoletta sfuggita all'altra e tutti i supporti della shell roba di fantasia.

>>> 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']

esempio di virgolette con escape:

>>> 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']

Altri suggerimenti

Dipende da quanto complicato desideri ottenere ... vuoi consentire più di un tipo di quotazione. Che ne dici di citazioni di escape?

La tua sintassi assomiglia molto al comune formato di file CSV, che è supportato dalla libreria standard di Python:

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

Uscite:

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

HTH!

Puoi anche prendere in considerazione il modulo csv . Non l'ho provato, ma sembra che i tuoi dati di input siano più vicini a CSV che alla sintassi della shell (che è ciò che shlex analizza).

Potresti fare qualcosa del genere:

>>> 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']

Direi che un'espressione regolare sarebbe ciò che stai cercando qui, anche se non ho molta familiarità con il motore Regex di Python.

Supponendo che tu usi corrispondenze pigre, puoi ottenere una serie di corrispondenze su una stringa che puoi inserire nel tuo array.

Se non è necessario essere belli, questo potrebbe farti arrivare:

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('"'))], [])
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top