JSON中的单引号与双引号

问题:JSON中的单引号与双引号

我的代码:

import simplejson as json

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

#1 定义是错误的

#2 定义是正确的

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

My code:

import simplejson as json

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

#1 definition is wrong

#2 definition is right

I heard that in Python that single and double quote can be interchangable. Can anyone explain this to me?


回答 0

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

JSON syntax is not Python syntax. JSON requires double quotes for its strings.


回答 1

您可以使用 ast.literal_eval()

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

you can use ast.literal_eval()

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

回答 2

您可以通过以下方式转储带有双引号的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) 

You can dump JSON with double quote by:

import json

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

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

回答 3

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 is also a good package to solve the problem of bad json syntax:

pip install demjson

Usage:

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

Edit:

demjson.decode is a great tool for damaged json, but when you are dealing with big amourt of json data ast.literal_eval is a better match and much faster.


回答 4

到目前为止,给出了两个问题的答案,例如,如果一个流这样的非标准JSON。因为这样一来,可能不得不解释传入的字符串(而不是python字典)。

问题1- demjson:使用Python 3.7。+并使用conda时,我无法安装demjson,因为它显然不支持Python> 3.5。因此,我需要一个具有更简单方法的解决方案,例如astand / or json.dumps

问题2- astjson.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(字典),但它不会转换我们所需的内容。

Two issues with answers given so far, if , for instance, one streams such non-standard JSON. Because then one might have to interpret an incoming string (not a python dictionary).

Issue 1 – demjson: With Python 3.7.+ and using conda I wasn’t able to install demjson since obviosly it does not support Python >3.5 currently. So I need a solution with simpler means, for instance astand/or json.dumps.

Issue 2 – ast & json.dumps: If a JSON is both single quoted and contains a string in at least one value, which in turn contains single quotes, the only simple yet practical solution I have found is applying both:

In the following example we assume line is the incoming JSON string object :

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

Step 1: convert the incoming string into a dictionary using ast.literal_eval()
Step 2: apply json.dumps to it for the reliable conversion of keys and values, but without touching the contents of values:

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

json.dumps alone would not do the job because it does not interpret the JSON, but only see the string. Similar for ast.literal_eval(): although it interprets correctly the JSON (dictionary), it does not convert what we need.


回答 5

您可以通过以下方式解决它:

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

You can fix it that way:

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

回答 6

如前所述,JSON不是Python语法。您需要在JSON中使用双引号。它的创建者以使用允许语法的严格子集来减轻程序员的认知负担而闻名。


如果一个JSON字符串本身包含一个单引号(如@Jiaaro所指出的),则以下内容可能会失败。不使用。此处以不起作用的示例为例。

这是非常有用的知道有一个JSON字符串没有单引号。说,您从浏览器控制台/任何地方复制并粘贴了它。然后,您可以输入

a = json.loads('very_long_json_string_pasted_here')

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

As said, JSON is not Python syntax. You need to use double quotes in JSON. Its creator is (in-)famous for using strict subsets of allowable syntax to ease programmer cognitive overload.


Below can fail if one of the JSON strings itself contains a single quote as pointed out by @Jiaaro. DO NOT USE. Left here as an example of what does not work.

It is really useful to know that there are no single quotes in a JSON string. Say, you copied and pasted it from a browser console/whatever. Then, you can just type

a = json.loads('very_long_json_string_pasted_here')

This might otherwise break if it used single quotes, too.


回答 7

使用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)

It truly solved my problem using eval function.

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)

回答 8

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

["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

希望它对某人有用。请享用!

I recently came up against a very similar problem, and believe my solution would work for you too. I had a text file which contained a list of items in the form:

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

I wanted to parse the above into a python list but was not keen on eval() as I couldn’t trust the input. I tried first using JSON but it only accepts double quoted items, so I wrote my own very simple lexer for this specific case (just plug in your own “stringtoparse” and you will get as output list: ‘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

Hopefully it is useful to somebody. Enjoy!


回答 9

import ast 
answer = subprocess.check_output(PYTHON_ + command, shell=True).strip()
    print(ast.literal_eval(answer.decode(UTF_)))

为我工作

import ast 
answer = subprocess.check_output(PYTHON_ + command, shell=True).strip()
    print(ast.literal_eval(answer.decode(UTF_)))

Works for me


回答 10

import json
data = json.dumps(list)
print(data)

上面的代码段应该可以正常工作。

import json
data = json.dumps(list)
print(data)

The above code snippet should work.