Как я могу разобрать строку, разделенную запятой, в список (предостережение)?

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

  •  02-07-2019
  •  | 
  •  

Вопрос

Мне нужно иметь возможность использовать строку, подобную:

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

Я бы сказал, что регулярное выражение было бы тем, что вы ищете здесь, хотя я не очень хорошо знаком с движком регулярных выражений 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('"'))], [])
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top