Кажется, это работает:
# [...]
matcher = re.compile(r'(?:("+)([\s\S]+?))(\1)|(.+)')
# [...]
производит:
[('', '', '', 'Line outside quotes'), ('', '', '', 'Another line'), ('"', 'Two lines inside\nnormal quotes', '"', ''), ('""', 'Two lines inside\nfancy "dual" quotes', '""', ''), ('"""', 'Three lines inside\n"even fancier"\ntriple quotes', '"""', ''), ('', '', '', 'Last line')]
Я заключил в кавычки строку в их собственных группах. Предложение «else», если вы можете так его назвать, имеет вид |(.+)
.
Так что, если первое поле пустое, оно является строкой без кавычек и содержится в последнем поле. Иначе, первые три поля содержат кавычки (перед + зад) и внутреннюю строку. Простого "".join(single_result_tuple)
для каждого результата должно быть достаточно:
# [...]
result = ["".join(r) for r in result]
# [...]
['Line outside quotes', 'Another line', '"Two lines inside\nnormal quotes"', '""Two lines inside\nfancy "dual" quotes""', '"""Three lines inside\n"even fancier"\ntriple quotes"""', 'Last line']
(С именованными группами вы можете лучше точно извлечь ваш правильный контент.)
И с перестановка групп: (оборачивая все в группу)
matcher = re.compile(r'(("+)[\s\S]+?\2|.+)')
вы можете получить:
[('Line outside quotes', ''), ('Another line', ''), ('"Two lines inside\nnormal quotes"', '"'), ('""Two lines inside\nfancy "dual" quotes""', '""'), ('"""Three lines inside\n"even fancier"\ntriple quotes"""', '"""'), ('Last line', '')]
Таким образом, вы можете проверить, какой стиль цитирования использовался. Содержимое находится в первом поле:
# [...]
result = [r[0] for r in result]
# [...]
Чтобы полностью получить только строку, необходимо выполнить некоторую постобработку. Ссылке \2
нужна группа (...)
, поэтому вы не можете исключить ее из результата с помощью ?:
. (Группа без захвата, если я правильно помню)