Comment puis-je analyser une chaîne délimitée par des virgules dans une liste (mise en garde)?

StackOverflow https://stackoverflow.com/questions/118096

  •  02-07-2019
  •  | 
  •  

Question

Je dois pouvoir prendre une chaîne telle que:

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

dans:

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

J'ai le sentiment (avec des indices de #python) que la solution impliquera le module shlex.

Était-ce utile?

La solution

La solution de module shlex permet les citations échappées, une citation en échappe, et tous les supports de shell sophistiqués.

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

Exemple de guillemets d'échappement:

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

Autres conseils

Cela dépend de la complexité de votre travail. Voulez-vous autoriser plusieurs types de devis? Qu'en est-il des citations échappées?

Votre syntaxe ressemble beaucoup au format de fichier CSV commun, qui est pris en charge par la bibliothèque standard Python:

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

Sorties:

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

HTH!

Vous pouvez également envisager le module csv . Je ne l’ai pas essayé, mais il semble que vos données d’entrée soient plus proches du format CSV que de la syntaxe du shell (ce qui est analysé par shlex).

Vous pouvez faire quelque chose comme ceci:

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

Je dirais que vous cherchez une expression régulière, bien que je ne connaisse pas très bien le moteur Regex de Python.

En supposant que vous utilisiez des correspondances paresseuses, vous pouvez obtenir un ensemble de correspondances sur une chaîne que vous pouvez placer dans votre tableau.

Si cela n’a pas besoin d’être joli, cela pourrait vous mettre sur la bonne voie:

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('"'))], [])
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top