У меня есть строка, которая выглядит примерно так:
x = """\
names=['m','c'], \
nmodes=2, \
mus=[[-5.0, -5.0], \
[5.0, 5.0]], \
sigmas=[[1.5, 1.5], [2.1, 2.1]], \
corrcoefs=[[[1.0, -0.7], [-0.7, 1.0]], [[1.0, 0.7], [0.7, 1.0]]], \
covs=[[[2.25, -1.5749999999999997], [-1.5749999999999997, 2.25]], [[4.41, 3.087], [3.087, 4.41]]], \
weights=[1.0, 3.0], \
bounds = {'m': (-inf, inf), 'c': (-inf, inf)}\
"""
Я хочу разбить его на пары ключ-значение, используя «=» в качестве разделителя и где каждая пара разделена запятой ","
.
Я пробовал следующее, используя re:
import re
re.findall("(\S+)=(\[.*\]$|{.*}$|\S+)", x)
который дает:
[('names', "['m','c'],"),
('nmodes', '2,'),
('mus', '[[-5.0,'),
('sigmas', '[[1.5,'),
('corrcoefs', '[[[1.0,'),
('covs', '[[[2.25,'),
('weights', '[1.0,'),
('bounds', "{'m': (-inf, inf), 'c': (-inf, inf)}")]
но некоторые списки обрезаются. Вывод, похоже, меняется в зависимости от количества пробелов после запятой в списках, но я хотел бы, чтобы он работал с произвольным количеством пробелов после запятых.
В идеале часть «значение» может быть любой строкой до последней запятой перед следующим ключом. Поскольку у меня были значения, которые были списками или словарями, которые сами содержали запятые, моя логика заключалась в том, чтобы попытаться включить эти случаи.
Вы не должны использовать $
, ваша строка не имеет разрывов строк.
Ты можешь использовать
re.findall(r'(\w+)=(\[.*?]|{.*?}|\S+)(?=\s*,\s*\w+=|\Z)', text)
См. демонстрация регулярных выражений. Подробности:
(\w+)
- Группа 1: один или несколько символов слова=
- =
символ(\[.*?]|{.*?}|\S+)
- Группа 2: [
, любой ноль или более символов, кроме символов разрыва строки, как можно меньше, ]
или {
, любой ноль или более символов, кроме символов разрыва строки, как можно меньше, }
, или один или более символы без пробелов(?=\s*,\s*\w+=|\Z)
- положительный просмотр вперед, для которого требуется запятая, заключенная в ноль или более пробелов, один или несколько символов слова, =
или конец строки.
Какова логика матчей? Должны ли они быть сбалансированными кронштейнами?