我有一串字典如下:
format
现在我希望pwd
此字符串动态替换name
和CREDENTIALS = "{\"aaaUser\": {\"attributes\": {\"pwd\": \"{0}\", \"name\": \"{1}\"}}}".format('password', 'username')
。我尝试过的是:
traceback (most recent call last):
File ".\ll.py", line 4, in <module>
CREDENTIALS = "{\"aaaUser\": {\"attributes\": {\"pwd\": \"{0}\", \"name\": \"{1}\"}}}".format('password', 'username')
KeyError: '"aaaUser"
但这会产生以下错误:
dict
只需使用json.loads()
将字符串加载为{{1}}然后根据需要设置属性即可,但这不是我想要的。我想格式化字符串,以便我可以在其他文件/模块中使用此字符串。
&#39;
我在这里失踪了什么?任何帮助,将不胜感激。
答案 0 :(得分:1)
请勿尝试直接使用JSON字符串;解码它,更新数据结构,并重新编码:
# Use single quotes instead of escaping all the double quotes
CREDENTIALS = '{"aaaUser": {"attributes": {"pwd": "cisco123", "name": "admin"}}}'
d = json.loads(CREDENTIALS)
attributes = d["aaaUser"]["attributes"]
attributes["name"] = username
attributes["pwd"] = password
CREDENTIALS = json.dumps(d)
使用字符串格式化,您需要将字符串更改为
CREDENTIALS = '{{"aaaUser": {{"attributes": {{"pwd": "{0}", "name": "{1}"}}}}}}'
将所有字面括号加倍,以便format
方法不会将它们误认为是占位符。
但是,格式化也意味着如果密码包含任何可能被误认为是JSON语法的内容(例如双引号),则需要对其进行预转义。
# This produces invalid JSON
NEW_CREDENTIALS = CREDENTIALS.format('new"password', 'bob')
# This produces valid JSON
NEW_CREDENTIALS = CREDENTIALS.format('new\\"password', 'bob')
解码和重新编码会更容易,更安全。
答案 1 :(得分:1)
str.format
处理括号{}
附带的文字。此处变量CREDENTIALS
的首字母为大括号{
,它遵循str.format
规则以替换它的文本,并找到立即关闭的大括号,因为它找不到它而是获得另一个开口大括号&#39; {&#39;这就是它抛出错误的原因。
调用此方法的字符串可以包含由大括号{}
分隔的文字文本或替换字段
现在要转义大括号并仅替换哪个缩进可以完成,如果包含两次,如
'{{ Hey Escape }} {0}'.format(12) # O/P '{ Hey Escape } 12'
如果您逃离父母和祖父母{}
,那么它将起作用。
示例:
'{{Escape Me {n} }}'.format(n='Yes') # {Escape Me Yes}
因此遵循str.format
的规则,我通过添加一个额外的括号来逃避括号括起来的父文本。
"{{\"aaaUser\": {{\"attributes\": {{\"pwd\": \"{0}\", \"name\": \"{1}\"}}}}}}".format('password', 'username')
#O/P '{"aaaUser": {"attributes": {"pwd": "password", "name": "username"}}}'
现在进行字符串格式化以使其工作。还有其他方法可以做到这一点。但是,在您的情况下不建议这样做,因为您需要确保问题始终具有您提到的格式并且永远不会与其他格式混淆,否则结果可能会发生巨大变化。
所以这里我所遵循的解决方案是使用字符串替换将格式从{0}
转换为%(0)s
,以便字符串格式化可以正常工作,而且从不关心大括号。
'Hello %(0)s' % {'0': 'World'} # Hello World
所以我在这里使用re.sub
替换所有出现的
def myReplace(obj):
found = obj.group(0)
if found:
found = found.replace('{', '%(')
found = found.replace('}', ')s')
return found
CREDENTIALS = re.sub('\{\d{1}\}', myReplace, "{\"aaaUser\": {\"attributes\": {\"pwd\": \"{0}\", \"name\": \"{1}\"}}}"% {'0': 'password', '1': 'username'}
print CREDENTIALS # It should print desirable result