2015-07-07 4 views
0

У меня есть ряд строк с json-форматом, например '{"key1":{0}, "key2":{1}}'.Как форматировать json строку в Python

После получения строки json и замены значений. '{"key1":{0}, "key2":{1}}'.format("value1", "value2"). # KeyError: '"key1"

Проблема вызвана кронштейном {, и я должен использовать {{ и }} в строке, однако, это не так легко добавить { к строке, потому что кронштейн может появиться в средней части, такие как '{"key1":{0}, "key2":{1}, "{3}":"value3"}'

Как форматировать строку json?

+0

Я не вижу проблемы. Формат, как и любая другая строка, а затем используйте 'json.loads' –

+0

@MalikBrahimi. Его проблема в том, что функция формата будет думать, что это блок форматирования, когда это не так. – CrazyCasta

+2

Попытка выполнить подстановку строк в строку JSON не является Pythonic и подвержена ошибкам. Вместо этого создайте значение в качестве словаря и используйте 'json.dumps'. – Kupiakos

ответ

2

Не пытайтесь манипулировать данными в виде закодированной строки. Декодируйте JSON, прежде чем пытаться применить форматирование.

import json 

json_data = '{"key1":"{0}","key2":"{1}"}' 
format_args = ["value1", "value2"] 

data = json.loads(json_data) 
formatted_data = {key: value.format(*format_args) for key, value in data.items()} 

После этого вы можете перекодировать форматированные данные как JSON.

+0

'Traceback (самый последний вызов последнего): Файл "питон", строка 7, в Файл "питон", строка 7, в IndexError: индекс кортежа из range' –

+0

I отредактировал ответ, чтобы предотвратить ошибку выше. Ему не хватало '*', чтобы сделать * reference * для массива для значений формата. –

+0

@LS Хороший улов, хотя '*' не имеет ничего общего с различием ссылки/значения. Он просто расширяет список до позиционных аргументов. См. Https://docs.python.org/2/tutorial/controlflow.html#unpacking-argument-lists. – augurar

2

Если вы строите эти строки самостоятельно или имеете контроль над ними, отправьте другой формат или создайте значение в качестве словаря и используйте json.dumps.

Однако, если вам действительно нужно это сделать, если это гарантирует, что значения замещения будет в формате {X}, то вы можете избежать строку с этим ляп:

import re 
s = '{"key1":{0}, "key2":{1}}' 
begin = re.compile(r'{(?!\d)') 
end = re.compile(r'(?<!\d)}') 
escaped = end.sub('}}', begin.sub('{{', s)) 
print(escaped.format(1, 2)) 

результаты в

{"key1":1, "key2":2} 

Обратите внимание, что это не лучшее решение. Учитывая, что у вас есть контроль над строками, вы должны избегать их каким-то другим способом. Может использоваться синтаксис % вместо str.format?

+0

Ваше регулярное выражение не удастся, если json string понравится: s = '{"key1": {0}, "key2": {1}, "key3": 5}' Итак, «конец» должен выглядеть следующим образом (я не уверен, поэтому я не редактирую ответ) end = re.compile (r '(?

Смежные вопросы