Мне нужно иметь строку, например:
'''foo, bar, "one, two", three four'''
в
['foo', 'bar', 'one, two', 'three four']
У меня есть чувство (с подсказками от #python), что решение будет включать модуль shlex.
Мне нужно иметь строку, например:
'''foo, bar, "one, two", three four'''
в
['foo', 'bar', 'one, two', 'three four']
У меня есть чувство (с подсказками от #python), что решение будет включать модуль shlex.
Решение модуля 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']
Это зависит от того, насколько сложно вы хотите получить... вы хотите разрешить более одного типа цитирования. Как насчет скрытых кавычек?
Ваш синтаксис очень похож на общий формат файла 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']
НТН!
Вы также можете рассмотреть модуль csv. Я не пробовал, но похоже, что ваши входные данные ближе к CSV, чем к синтаксису оболочки (это то, что анализирует shlex).
Вы можете сделать что-то вроде этого:
>>> 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']
Я бы сказал, что регулярное выражение будет тем, что вы ищете здесь, хотя я не очень хорошо знаком с механизмом Regex Python.
Предполагая, что вы используете ленивые совпадения, вы можете получить набор совпадений в строке, которую вы можете поместить в свой массив.
Если вам не нужно быть красивым, это может помочь вам:
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('"'))], [])