JavaScript parse function JSON.parse does not work as expected - javascript

The case:
var s = '{"a": 2}';
var d = JSON.parse(s); // d = Object {a: 2}
It is OK.
The similar case does not parse string, however. Why?
var s = "{'a': 2}";
var d= JSON.parse(s) // Uncaught SyntaxError: Unexpected token ' in JSON at position 1
Expected result - parsed object like in the first case. It should have worked because ' and " are interchangeable in javascript.

According to the standard, you need double quotes to denotes a string, which a key is.

It should have worked because ' and " are interchangeable in javascript.
JSON is not JavaScript.
JSON strings must be delimited with quotation marks, not apostrophes.
See the specification:
A string begins and ends with quotation marks.

Related

nodejs REPL doesn't process JSON.parse()?

I'm trying node with REPL, parsing from string failed like this:
$node
> var str="{'a':1,'b':2}"
undefined
> var js=JSON.parse(str)
SyntaxError: Unexpected token ' in JSON at position 1
But the reversed parse seems OK:
> var json = {a : ' 1 ',b : ' 2'};
undefined
> var str = JSON.stringify(json);
undefined
> str
'{"a":" 1 ","b":" 2"}'
Where did I get wrong?
You have syntax error in your JSON:
{'a':1,'b':2}
^
|
'--- invalid syntax. Illegal character (')
JSON is not the same thing as Javascript object literals. JSON is a file/data format which is compatible with object literal syntax but is more strict. The JSON format was specified by Douglas Crockford and documented at http://json.org/
Some of the differences between JSON and object literals:
Property names are strings
Strings start and end with double quotes (")
Hexadecimals numbers (eg. 0x1234) are not supported
etc.

Parsing string as JSON with single quotes?

I have a string
str = "{'a':1}";
JSON.parse(str);
VM514:1 Uncaught SyntaxError: Unexpected token '(…)
How can I parse the above string (str) into a JSON object ?
This seems like a simple parsing. It's not working though.
The JSON standard requires double quotes and will not accept single quotes, nor will the parser.
If you have a simple case with no escaped single quotes in your strings (which would normally be impossible, but this isn't JSON), you can simple str.replace(/'/g, '"') and you should end up with valid JSON.
I know it's an old post, but you can use JSON5 for this purpose.
<script src="json5.js"></script>
<script>JSON.stringify(JSON5.parse('{a:1}'))</script>
If you are sure your JSON is safely under your control (not user input) then you can simply evaluate the JSON. Eval accepts all quote types as well as unquoted property names.
var str = "{'a':1}";
var myObject = (0, eval)('(' + str + ')');
The extra parentheses are required due to how the eval parser works.
Eval is not evil when it is used on data you have control over.
For more on the difference between JSON.parse and eval() see JSON.parse vs. eval()
Using single quotes for keys are not allowed in JSON. You need to use double quotes.
For your use-case perhaps this would be the easiest solution:
str = '{"a":1}';
Source:
If a property requires quotes, double quotes must be used. All
property names must be surrounded by double quotes.
var str = "{'a':1}";
str = str.replace(/'/g, '"')
obj = JSON.parse(str);
console.log(obj);
This solved the problem for me.
Something like this:
var div = document.getElementById("result");
var str = "{'a':1}";
str = str.replace(/\'/g, '"');
var parsed = JSON.parse(str);
console.log(parsed);
div.innerText = parsed.a;
<div id="result"></div>
// regex uses look-forwards and look-behinds to select only single-quotes that should be selected
const regex = /('(?=(,\s*')))|('(?=:))|((?<=([:,]\s*))')|((?<={)')|('(?=}))/g;
str = str.replace(regex, '"');
str = JSON.parse(str);
The other answers simply do not work in enough cases. Such as the above cited case: "title": "Mama's Friend", it naively will convert the apostrophe unless you use regex. JSON5 will want the removal of single quotes, introducing a similar problem.
Warning: although I believe this is compatible with all situations that will reasonably come up, and works much more often than other answers, it can still break in theory.
sometimes you just get python data, it looks a little bit like json but it is not. If you know that it is pure python data, then you can eval these data with python and convert it to json like this:
echo "{'a':1}" | /usr/bin/python3 -c "import json;print(json.dumps(eval(input())))"
Output:
{"a": 1}
this is good json.
if you are in javascript, then you could use JSON.stringify like this:
data = {'id': 74,'parentId': null};
console.log(JSON.stringify(data));
Output:
> '{"id":74,"parentId":null}'
If you assume that the single-quoted values are going to be displayed, then instead of this:
str = str.replace(/\'/g, '"');
you can keep your display of the single-quote by using this:
str = str.replace(/\'/g, '\&apos;\');
which is the HTML equivalent of the single quote.
json = ( new Function("return " + jsonString) )();

Convert string from regexp match into object

I have the following string:
var str = 'jfkdjffddf{aaa:12,bbb:25}kfdjf';
And I want to fetch the object from it:
var objStr = str.match('/{(.*?)}/')[1]; // aaa:12,bbb:25
Now I want to use this fetched string as an object:
var obj = JSON.parse('{' + objStr + '}');
Do some operations on it, convert to string back again and replace in the initial text.
The problem is I get unexpected token a on 1 line in my script, the problem is thus probably JSON.parse.
What's the problem, and how can I solve this?

convert invalid JSON string to JSON

I have an invalid json string like following,
"{one: 'one', two: 'two'}"
I tried to use JSON.parse to convert it to an object. however, this is not valid json string.
Is there any functions can convert this invalid format into a valid json string or directly convert into an object?
IF your example syntax is the same as your real JSON, JSONLint says you need double quote for the name AND the value.
In this case only, use these replace calls:
var jsontemp = yourjson.replace((/([\w]+)(:)/g), "\"$1\"$2");
var correctjson = jsontemp.replace((/'/g), "\"");
//yourjson = "{one: 'one', two: 'two'}"
//jsontemp = "{"one": 'one', "two": 'two'}"
//correctjson = "{"one": "one", "two": "two"}"
However you should try to work with a valid Json in the first place.
If the question is "can I convert invalid JSON into valid JSON", in the general case the answer is obviously "no"; where would you even start with a string like "$#!~~"?
In this particular case, the JSON is only invalid because the property names are not quoted; as JavaScript, the string is valid and could be parsed using, for example,
var myObj = eval( "x=" + myString );
or better
var myObj = (new Function("return " + myString))();
However, this is potentially very unsafe and you should not do it unless you are positive the string cannot cause harm (which seems unlikely if you aren't in a position to generate valid JSON in the first place). It also won't help you if the JSON code is invalid in other ways, and it will fail if the property names are not valid JS identifiers.
For a proper answer it would be useful to know more about the context of this question.

Replacing " with \"

I'm trying to replace all " with \" and parse string with JSON but browser throws an error SyntaxError: JSON Parse error: Unrecognized token '\'.
Below is code. String a is JSON.parsed well, but although I replace all " with \" in string b, so that it should be identical to string a, the parsing fails. I have the code in JSBIN.
var a = '[\"{\\"objects\\":[],\\"background\\":\\"#fff\\"}\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]';
var b = '["{\"objects\":[],\"background\":\"#fff\"}","","","","","","","","",""]';
// Replace " with \"
// Charcode 92 is \
b = b.replace('"', String.fromCharCode(92)+'"', "g");
a = JSON.parse(a);
console.log(a);
b = JSON.parse(b);
console.log(b);
Any idea, how I could string b parsed with JSON.parse? If I replace all " with \" manually, it parses well, but I'm seeking automated way.
the point is using 2 \:
b = b.replace(/"/g,'\\"')
and the result is:
[\"{\"objects\":[],\"background\":\"#fff\"}\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"]
as #isherwood, has said:
To be more clear, the backslash is an escape character, so you need to
double it so there's an actual character behind the escape.
Try using this:
b = b.replace(/"(?=[^\{]*\})/g, '\\"');
This will replace all the " within braces to \".
The first string a becomes actually:
["{\"objects\":[],\"background\":\"#fff\"}","","","","","","","","",""]
And that's what you have to make b become, except that just after making the variable, it becomes:
["{"objects":[],"background":"#fff"}","","","","","","","","",""]
So you actually have to put some \ back where they should be.
But since you are trying to parse JSON, you might be better off with:
b = JSON.stringify(b);

Categories