Разделить строку, игнорируя разделитель в кавычках (python)

Я хотел бы разбить строку на запятую, но игнорировать случаи, когда она находится в кавычках:

например:

teststring = '48, "one, two", "2011/11/03"'
teststring.split(",")
['48', ' "one', ' two"', ' "2011/11/03"']

и вывод, который мне нужен, следующий:

['48', ' "one, two"', ' "2011/11/03"']

Возможно ли это?

Ответ 1

Модуль csv будет работать, если вы установите параметры для обработки этого диалекта:

>>> import csv
>>> teststring = '48, "one, two", "2011/11/03"'
>>> for line in csv.reader([teststring], skipinitialspace=True):
    print line


['48', 'one, two', '2011/11/03']

Ответ 2

Вы можете использовать модуль csv из стандартной библиотеки:

>>> import csv
>>> testdata = ['48, "one, two", "2011/11/03"']
>>> testcsv = csv.reader(testdata,skipinitialspace=True)
>>> testcsv.next()
['48', 'one, two', '2011/11/03']

Единственное, на что нужно обратить внимание, - это то, что объекты csv.reader ожидают iterator, которые будут возвращать строку каждый раз, когда вызывается next(). Это означает, что вы не можете передать строковую строку прямо в reader(), но вы можете заключить ее в список, как указано выше.

Вам нужно быть осторожным с форматом ваших данных или сообщить csv, как его обрабатывать. По умолчанию кавычки должны появляться сразу после того, как запятая или модуль csv интерпретирует это поле как начало с пробелом, а не с кавычками. Вы можете исправить это, используя параметр skipinitialspace.

Ответ 3

Вы можете использовать модуль shlex для анализа вашей строки.

По умолчанию shlex.split разделит вашу строку на пробельные символы, не заключенные в кавычки:

>>> shlex.split(teststring)
['48,', 'one, two,', '2011/11/03']

Это не удаляет конечные запятые из вашей строки, но это близко к тому, что вам нужно. Однако, если вы настроите парсер для рассмотрения запятой как символа пробела, вы получите нужный вам результат:

>>> parser = shlex.shlex(teststring)
>>> parser.whitespace
' \t\r\n'
>>> parser.whitespace += ','
>>> list(parser)
['48', '"one, two"', '"2011/11/03"']

Примечание: объект-парсер используется как итератор для получения токенов один за другим. Следовательно, list(parser) выполняет итерацию над объектом парсера и возвращает строку, расщепляемую там, где вам нужно.

Ответ 5

import shlex
teststring = '48, "one, two", "2011/11/03"'
output = shlex.split(teststring)
output = [re.sub(r",$","",w) for w in output]
print output
['48', 'one, two', '2011/11/03']