【问题标题】:Single vs double quotes in JSONJSON中的单引号和双引号
【发布时间】: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 引号可以互换。谁能给我解释一下?

【问题讨论】:

    标签: python json


    【解决方案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
      

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

      【讨论】:

      【解决方案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 应该可以工作。

          【讨论】:

          • 它可能会做一些有用的事情,但它不能回答所提出的问题。问题始于一个字符串,而不是一个列表。
          猜你喜欢
          • 2012-04-24
          • 1970-01-01
          • 2012-12-30
          • 1970-01-01
          • 2013-02-16
          • 1970-01-01
          • 2013-12-14
          • 2013-02-16
          相关资源
          最近更新 更多