Большинство ответов кажутся слишком сложными. Вам не нужны обратные ссылки. Вы не должны зависеть от того, дает ли re.findall перекрывающиеся совпадения. Принимая во внимание, что входные данные не могут быть проанализированы с помощью модуля csv, поэтому регулярное выражение - это, пожалуй, единственный путь, все, что вам нужно, это вызвать re.split с шаблоном, который соответствует полю.
Обратите внимание, что здесь намного проще сопоставить поле, чем сопоставить разделитель:
import re
data = """part 1;"this is ; part 2;";'this is ; part 3';part 4;this "is ; part" 5"""
PATTERN = re.compile(r'''((?:[^;"']|"[^"]*"|'[^']*')+)''')
print PATTERN.split(data)[1::2]
и вывод:
['part 1', '"this is ; part 2;"', "'this is ; part 3'", 'part 4', 'this "is ; part" 5']
Как правильно заметил Жан-Люк Насиф Коэльо, это не будет правильно обрабатывать пустые группы. В зависимости от ситуации, которая может иметь или не иметь значения. Если это имеет значение, возможно, можно будет обработать его, например, заменив ';;'
на ';<marker>;'
, где <marker>
должна быть некоторой строкой (без точек с запятой), которую, как вы знаете, не будет в данных до разделения , Также вам необходимо восстановить данные после:
>>> marker = ";!$%^&;"
>>> [r.replace(marker[1:-1],'') for r in PATTERN.split("aaa;;aaa;'b;;b'".replace(';;', marker))[1::2]]
['aaa', '', 'aaa', "'b;;b'"]
Однако это клудж. Есть лучшие предложения?