Подтвердить что ты не робот

Как я могу разобрать строку с разделителями-запятыми в список (оговорка)?

Мне нужно иметь строку, например:

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

в

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

У меня есть чувство (с подсказками от #python), что решение будет включать модуль shlex.

4b9b3361

Ответ 1

Решение модуля shlex позволяет избежать кавычек, одна цитата уберет другую и поддерживает все полезные оболочки.

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

экранированный кавычек:

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

Ответ 2

Это зависит от того, насколько сложно вы хотите получить... вы хотите разрешить более одного типа цитирования. Как насчет скрытых кавычек?

Ваш синтаксис очень похож на общий формат файла CSV, который поддерживается стандартной библиотекой Python:

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

Выходы:

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

НТН!

Ответ 3

Вы также можете рассмотреть модуль csv. Я не пробовал, но похоже, что ваши входные данные ближе к CSV, чем к синтаксису оболочки (это то, что анализирует shlex).

Ответ 4

Вы можете сделать что-то вроде этого:

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

Ответ 5

Я бы сказал, что регулярное выражение будет тем, что вы ищете здесь, хотя я не очень хорошо знаком с механизмом Regex Python.

Предполагая, что вы используете ленивые совпадения, вы можете получить набор совпадений в строке, которую вы можете поместить в свой массив.

Ответ 6

Если вам не нужно быть красивым, это может помочь вам:

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('"'))], [])