Convert string with single quotes to json python

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.

Sometimes, you may got this:-

data = "{'name': 'kamal', 'address': 'jb'}"

but json.loads(data) would refuse this as json require double quotes. You can use ast.literal_eval() instead.

data_dict = ast.literal_eval(data)

Related protips

convert single quote json data file to double quote json data file (without mangling inner quotes)

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

__author__ = 'mbrzustowicz'
# metadata.json has single quotes like this
# {'asin': 'B00M0AEPXG', 'imUrl': 'http://ecx.images-amazon.com/images/I/51hcXTUeHLL._BO2,204,203,200_ ..... }
# so the strategy is to read each line as a string, and dump into a REAL json file
import json
import ast
fr=open("/Users/mbrzustowicz/Downloads/metadata.json")
fw=open("/Users/mbrzustowicz/amazon_product_metadata.json", "w")
for line in fr:
json_dat = json.dumps(ast.literal_eval(line))
dict_dat = json.loads(json_dat)
json.dump(dict_dat, fw)
fw.write("\n")
fw.close()
fr.close()

JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1) #

The Python "JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)" occurs when we try to parse an invalid JSON string (e.g. single-quoted keys or values, or a trailing comma). Use the ast.literal_eval() method to solve the error.

Here is an example of how the error occurs.

Copied!

import json invalid_json = r"{'name': 'Alice'}" # ⛔️ json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1) result = json.loads(invalid_json)

Notice that the string has a single-quoted key and value, which means that it isn't a valid JSON string.

JSON (string) keys and values must be enclosed in double quotes.

Rather, it's just a Python dictionary that's wrapped in a string.

You can solve the error by using the ast.literal_eval method to evaluate the string that contains a Python literal.

Copied!

import ast invalid_json = r"{'name': 'Alice'}" result = ast.literal_eval(invalid_json) print(type(result)) # 👉️ print(result) # 👉️ {'name': 'Alice'} print(result['name']) # 👉️ Alice

The ast.literal_eval method allows us to safely evaluate a string that contains a Python literal.

The string may consist of strings, bytes, numbers, tuples, lists, dicts, sets, booleans and None.

An alternative approach is to use the str.replace() method to replace all single quotes in the string with double quotes.

Copied!

import json invalid_json = r"{'name': 'Alice'}" valid_json = invalid_json.replace("\'", "\"") print(valid_json) # 👉️ '{"name": "Alice"}' my_dict = json.loads(valid_json) print(my_dict) # 👉️ {'name': 'Alice'} print(type(my_dict)) # 👉️

However, this is very risky because the string could contain a single quote somewhere in its content, e.g. It's her.

You can also use the ast.literal_eval method if your string contains a trailing comma.

Copied!

import ast invalid_json = r'{"name": "Alice",}' result = ast.literal_eval(invalid_json) print(type(result)) # 👉️ print(result) # 👉️ {'name': 'Alice'} print(result['name']) # 👉️ Alice

The trailing comma also makes the string invalid JSON, but Python dictionaries are allowed to have a trailing comma after the last key-value pair.

Alternatively, you can try using the yaml.safe_load() method.

Make sure you have pyyaml installed by running pip install pyyaml.

Copied!

import yaml invalid_json = r'{"name": "Alice",}' # 👈️ has trailing comma my_dict = yaml.safe_load(invalid_json) print(my_dict) # 👉️ {'name': 'Alice'} print(type(my_dict)) # 👉️

Make sure the value you are trying to parse is a JSON string and has not been already parsed into a native Python object.

If you need to parse a JSON string into a native Python object, you have to use the json.loads() method, and if you need to convert a Python object into a JSON string, you have to use the json.dumps() method.

Copied!

import json json_str = r'{"name": "Alice", "age": 30}' # ✅ parse JSON string to Python native dict my_dict = json.loads(json_str) print(type(my_dict)) # 👉️ # ✅ convert Python native dict to a JSON string my_json_str = json.dumps(my_dict) print(type(my_json_str)) # 👉️

The json.loads() method basically helps us load a Python native object (e.g. a dictionary or a list) from a JSON string.

The json.dumps method converts a Python object to a JSON formatted string.

The JSONEncoder class supports the following objects and types by default.

PythonJSON
dict object
list, tuple array
str string
int, float, int and float derived Enums number
True true
False false
None null

If you aren't sure what type of object a variable stores, use the built-in type() class.

Copied!

my_dict = {'name': 'Alice', 'age': 30} print(type(my_dict)) # 👉️ print(isinstance(my_dict, dict)) # 👉️ True my_str = 'hello world' print(type(my_str)) # 👉️ print(isinstance(my_str, str)) # 👉️ True

The type class returns the type of an object.

The isinstance function returns True if the passed in object is an instance or a subclass of the passed in class.

Conclusion #

The Python "JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)" occurs when we try to parse an invalid JSON string (e.g. single-quoted keys or values, or a trailing comma). Use the ast.literal_eval() method to solve the error.

Can I use single quotes in JSON?

Strings in JSON are specified using double quotes, i.e., " . If the strings are enclosed using single quotes, then the JSON is an invalid JSON .

How do you convert a string to a JSON object in Python?

you can turn it into JSON in Python using the json. loads() function. The json. loads() function accepts as input a valid string and converts it to a Python dictionary.

Does JSON use double or single quotes?

JSON is standardized to use double-quotes, to the degree that this would not be considered standard JSON and would error in a JSON parser.

How do you escape a quote in JSON?

Backspace to be replaced with \b..
Form feed to be replaced with \f..
Newline to be replaced with \n..
Carriage return to be replaced with \r..
Tab to be replaced with \t..
Double quote to be replaced with \".
Backslash to be replaced with \\.