JSON中的单引号和双引号

Posted

技术标签:

【中文标题】JSON中的单引号和双引号【英文标题】:Single vs double quotes in JSON 【发布时间】:2011-05-08 22:31:22 【问题描述】:

我的代码:

import simplejson as json

s = "'username':'dfdsfdsf'" #1
#s = '"username":"dfdsfdsf"' #2
j = json.loads(s)

#1定义错误

#2定义是对的

我听说在 Python 中 singledouble 引号可以互换。谁能给我解释一下?

【问题讨论】:

【参考方案1】:

JSON syntax 不是 Python 语法。 JSON 的字符串需要双引号。

【讨论】:

但第一个是 JSON 中的单引号,我很困惑。那个可以通过编译,但是第二个不能。 感谢您的确认。显然我是唯一一个导入str(dict) 的人,并且不想eval 它。一个简单的.replace("'", '"') 就可以解决问题。 我说得太早了。显然它比这更复杂。 如果你需要使用双引号,你可以调用json.dumps(..) 两次:import json; d = dict(tags=["dog", "cat", "mouse"]); print json.dumps(json.dumps(d)) 得到:"\"tags\": [\"dog\", \"cat\", \"mouse\"]"【参考方案2】:

你可以使用ast.literal_eval()

>>> import ast
>>> s = "'username':'dfdsfdsf'"
>>> ast.literal_eval(s)
'username': 'dfdsfdsf'

【讨论】:

我最喜欢这个答案:你通常没有选择:如果有人给你单引号,你就会得到单引号。 json.loads 需要一个额外的参数,或者你应该使用它。全局替换“'”是一场灾难,如果传入的数据是: 'a' : 'this "string" really isn\'t!!!!' @Mark,这种方法可以适应嵌套引号的棘手情况,例如"'link':'<a href="mylink">http://my.com</a>'" 吗?在这种情况下,ast.literal_eval 会抛出语法错误 这对我来说似乎是一个安全风险。 ast.literal_eval 不是安全风险,它的eval 是。 我宁愿使用repr,因为literal_eval 在这方面过于强大了。【参考方案3】:

您可以通过以下方式转储带双引号的 JSON:

import json

# mixing single and double quotes
data = 'jsonKey': 'jsonValue',"title": "hello world"

# get string with all double quotes
json_string = json.dumps(data) 

【讨论】:

这走错路了。您正在将 python 数据结构序列化为 JSON;最初的问题是关于将 JSON 反序列化为 python 数据结构。 这个想法是用json.dumps将python序列化为json,然后在str格式的时候调用json.loads。 你在这里错过了解。如果要加载 json 字符串,它必须是双引号。你正在做的仍然是转储 json,而不是 json 字符串。 谢谢,这对我有用! json.loads(json.dumps(single_quotes_json)) 不确定最初的问题,但这肯定有助于我在将 JSON 数据插入 SQL Server 之前使用双引号正确翻译 JSON 数据以允许进行有效的 JSON 解析。谢谢!【参考方案4】:

到目前为止给出的答案有两个问题,例如,一个流式传输此类非标准 JSON。因为那时可能必须解释传入的字符串(而不是 python 字典)。

问题 1 - demjson: 使用 Python 3.7.+ 并使用 conda 我无法安装 demjson,因为显然它目前不支持 Python >3.5。所以我需要一个更简单的解决方案,例如ast和/或json.dumps

问题 2 - ast & json.dumps: 如果 JSON 既是单引号,又在至少一个值中包含一个字符串,而该字符串又包含单引号,那么我发现的唯一简单但实用的解决方案是同时应用这两者:

在以下示例中,我们假设 line 是传入的 JSON 字符串对象:

>>> line = str('abc':'008565','name':'xyz','description':'can control TV\'s and more')

第 1 步:使用 ast.literal_eval() 将传入的字符串转换为字典 第 2 步:对其应用 json.dumps 以实现键和值的可靠转换,但不涉及值的内容

>>> import ast
>>> import json
>>> print(json.dumps(ast.literal_eval(line)))
"abc": "008565", "name": "xyz", "description": "can control TV's and more"

json.dumps 单独无法完成这项工作,因为它不解释 JSON,而只看到字符串。 ast.literal_eval() 类似:虽然它正确解释了 JSON(字典),但它不会转换我们需要的内容。

【讨论】:

【参考方案5】:

demjson也是一个很好的包,可以解决json语法不好的问题:

pip install demjson

用法:

from demjson import decode
bad_json = "'username':'dfdsfdsf'"
python_dict = decode(bad_json)

编辑:

demjson.decode 是处理损坏 json 的好工具,但是当您处理大量 json 数据时,ast.literal_eval 是更好的匹配,而且速度更快。

【讨论】:

demjson.decode 是处理损坏 json 的好工具——但对于涉及数万或数十万个 json 数据包的任务,ast.literal_eval 速度要快得多。并不是说 demjson 没有它的位置:我将它用作备用方法,以防更快的方法失败。 实际上 demjson 的效果要好得多,而不是针对 ast.literal_eval 和 json.loads 进行测试【参考方案6】:

你可以这样修复它:

s = "'username':'dfdsfdsf'"
j = eval(s)

【讨论】:

使用 ast.literal_eval 代替 eval 来帮助避免注入攻击【参考方案7】:

如前所述,JSON 不是 Python 语法。您需要在 JSON 中使用双引号。它的创建者(臭名昭著)以使用允许语法的严格子集来缓解程序员的认知过载而闻名。


如果其中一个 JSON 字符串本身包含 @Jiaaro 所指出的单引号,则下面可能会失败。不使用。留在这里作为不起作用的示例。

知道 JSON 字符串中没有单引号非常有用。说,您从浏览器控制台/其他任何地方复制并粘贴了它。然后,您只需键入

a = json.loads('very_long_json_string_pasted_here')

如果它也使用单引号,这可能会中断。

【讨论】:

json 字符串中没有单引号是不正确的。在特定情况下这可能是正确的,但您不能依赖它。例如,这是有效的 json:"key": "value 'with' single quotes"【参考方案8】:

它使用 eval 函数真正解决了我的问题。

single_quoted_dict_in_string = "'key':'value', 'key2': 'value2'"
desired_double_quoted_dict = eval(single_quoted_dict_in_string)
# Go ahead, now you can convert it into json easily
print(desired_double_quoted_dict)

【讨论】:

这是一个非常糟糕的例子。如果有人发现你在 json 上使用了 eval 并发送了一个格式错误的 json,其中包含然后由 eval 评估的代码怎么办?【参考方案9】:

我最近遇到了一个非常相似的问题,并且相信我的解决方案也对您有用。我有一个文本文件,其中包含表单中的项目列表:

["first item", 'the "Second" item', "thi'rd", 'some \\"hellish\\" \'quoted" item']

我想将上面的内容解析成一个 python 列表,但不热衷于 eval(),因为我无法信任输入。我首先尝试使用 JSON,但它只接受双引号项目,所以我为这种特定情况编写了自己的非常简单的词法分析器(只需插入你自己的“stringtoparse”,你将得到输出列表:'items')

#This lexer takes a JSON-like 'array' string and converts single-quoted array items into escaped double-quoted items,
#then puts the 'array' into a python list
#Issues such as  ["item 1", '","item 2 including those double quotes":"', "item 3"] are resolved with this lexer
items = []      #List of lexed items
item = ""       #Current item container
dq = True       #Double-quotes active (False->single quotes active)
bs = 0          #backslash counter
in_item = False #True if currently lexing an item within the quotes (False if outside the quotes; ie comma and whitespace)
for c in stringtoparse[1:-1]:   #Assuming encasement by brackets
    if c=="\\": #if there are backslashes, count them! Odd numbers escape the quotes...
        bs = bs + 1
        continue                    
    if (dq and c=='"') or (not dq and c=="'"):  #quote matched at start/end of an item
        if bs & 1==1:   #if escaped quote, ignore as it must be part of the item
            continue
        else:   #not escaped quote - toggle in_item
            in_item = not in_item
            if item!="":            #if item not empty, we must be at the end
                items += [item]     #so add it to the list of items
                item = ""           #and reset for the next item
            continue                
    if not in_item: #toggle of single/double quotes to enclose items
        if dq and c=="'":
            dq = False
            in_item = True
        elif not dq and c=='"':
            dq = True
            in_item = True
        continue
    if in_item: #character is part of an item, append it to the item
        if not dq and c=='"':           #if we are using single quotes
            item += bs * "\\" + "\""    #escape double quotes for JSON
        else:
            item += bs * "\\" + c
        bs = 0
        continue

希望它对某人有用。享受吧!

【讨论】:

这为您提供了docs.python.org/2/library/ast.html#ast.literal_eval所没有的什么?【参考方案10】:

你可以使用

json.dumps(your_json, separators=(",", ":"))

【讨论】:

【参考方案11】:
import ast 
answer = subprocess.check_output(PYTHON_ + command, shell=True).strip()
    print(ast.literal_eval(answer.decode(UTF_)))

为我工作

【讨论】:

【参考方案12】:
import json
data = json.dumps(list)
print(data)

上面的代码 sn-p 应该可以工作。

【讨论】:

它可能会做一些有用的事情,但它不能回答所提出的问题。问题始于一个字符串,而不是一个列表。

以上是关于JSON中的单引号和双引号的主要内容,如果未能解决你的问题,请参考以下文章

JS中的单引号和双引号

SQL语言中的单引号与双引号区别

SQL Server 中的单引号和双引号

perl中的单引号和双引号

shell中的单引号和双引号的区别

r Markdown的Yaml标头中的单引号和双引号有啥区别?