json 值同时包含引号和双引号的 Jinja2 渲染问题
Jinja2 rendering issues with json values that contains both quotes and double quotes
我正在尝试使用包含引号和双引号的字符串值加载 json 文件。
如果我加载此文件(json ou yaml)并在 jinja2 渲染模板中使用它,如果我尝试使用 json 或 yaml 解析器加载结果,则会出现错误。
例如这个 json 文件:
{
"k": "\"v1\"='v2'"
}
以下代码失败(使用 json 解析器):
import json
from jinja2 import Environment
j = json.loads('{"k": "\"v1\"=\'v2\'"}')
t = Environment().from_string('{{ d }}')
r = t.render({'d': j})
# print(r)=> {'k': '"v1"=\'v2\''}
y = json.loads(r)
错误:json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
或者使用 yaml 解析器:
import yaml
from jinja2 import Environment
j = yaml.safe_load('{"k": "\"v1\"=\'v2\'"}')
t = Environment().from_string('{{ d }}')
r = t.render({'d': j})
# print(r)=> {'k': '"v1"=\'v2\''}
y = yaml.safe_load(r)
返回此错误:yaml.parser.ParserError: while parsing a flow mapping in "<unicode string>", line 1, column 1: {'k': '"v1"=\'v2\''}
我认为错误出在我的 jinja2 渲染参数中,但如何解决?
注意:如果我只使用双引号 (j = json.loads('{"k": "\"v1\""}')
) 或只使用单引号 (j = json.loads('{"k": "\'v2\'"}')
)
没有问题
{'k': '"v1"=\'v2\''}
既不是有效的 JSON 也不是 YAML。这是因为 JSON 专门支持双引号字符串,而 YAML 确实支持单引号字符串,但它们不处理转义序列。
Jinja 以这种方式呈现它,因为它是有效的 Python。 Jinja 不知道您要将其解析为 JSON 或 YAML。如果你想稍后再次将它加载为 JSON,你必须将结构序列化为 JSON:
import json
from jinja2 import Environment
j = json.loads('{"k": "\"v1\"=\'v2\'"}')
t = Environment().from_string('{{ d }}')
r = t.render({'d': json.dumps(j)})
# print(r)=> {"k": "\"v1\"='v2'"}
y = json.loads(r)
print(y)
如您所见,我将 j
替换为 json.dumps(j)
以便 Jinja 输出正确的 JSON – 您可以看到 r
现在包含两个双引号字符串。
在这个例子中,你甚至不需要将原始字符串加载到 j
中,因为你可以直接将它传递给 Jinja,但我假设你想在传递到模板。
我正在尝试使用包含引号和双引号的字符串值加载 json 文件。
如果我加载此文件(json ou yaml)并在 jinja2 渲染模板中使用它,如果我尝试使用 json 或 yaml 解析器加载结果,则会出现错误。
例如这个 json 文件:
{
"k": "\"v1\"='v2'"
}
以下代码失败(使用 json 解析器):
import json
from jinja2 import Environment
j = json.loads('{"k": "\"v1\"=\'v2\'"}')
t = Environment().from_string('{{ d }}')
r = t.render({'d': j})
# print(r)=> {'k': '"v1"=\'v2\''}
y = json.loads(r)
错误:json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
或者使用 yaml 解析器:
import yaml
from jinja2 import Environment
j = yaml.safe_load('{"k": "\"v1\"=\'v2\'"}')
t = Environment().from_string('{{ d }}')
r = t.render({'d': j})
# print(r)=> {'k': '"v1"=\'v2\''}
y = yaml.safe_load(r)
返回此错误:yaml.parser.ParserError: while parsing a flow mapping in "<unicode string>", line 1, column 1: {'k': '"v1"=\'v2\''}
我认为错误出在我的 jinja2 渲染参数中,但如何解决?
注意:如果我只使用双引号 (j = json.loads('{"k": "\"v1\""}')
) 或只使用单引号 (j = json.loads('{"k": "\'v2\'"}')
)
{'k': '"v1"=\'v2\''}
既不是有效的 JSON 也不是 YAML。这是因为 JSON 专门支持双引号字符串,而 YAML 确实支持单引号字符串,但它们不处理转义序列。
Jinja 以这种方式呈现它,因为它是有效的 Python。 Jinja 不知道您要将其解析为 JSON 或 YAML。如果你想稍后再次将它加载为 JSON,你必须将结构序列化为 JSON:
import json
from jinja2 import Environment
j = json.loads('{"k": "\"v1\"=\'v2\'"}')
t = Environment().from_string('{{ d }}')
r = t.render({'d': json.dumps(j)})
# print(r)=> {"k": "\"v1\"='v2'"}
y = json.loads(r)
print(y)
如您所见,我将 j
替换为 json.dumps(j)
以便 Jinja 输出正确的 JSON – 您可以看到 r
现在包含两个双引号字符串。
在这个例子中,你甚至不需要将原始字符串加载到 j
中,因为你可以直接将它传递给 Jinja,但我假设你想在传递到模板。