0

I need to parse a JSON string such as that shown below:

var json = 
"{\
foo: {\
 bar: 'something',\
 baz: {\
 jack: 'other',\
 jill: 5\
 },\
 bob: {\
 bill: 'hello',\
 bilbo: 11,\
 baggins: {\
 fizz: 'buzz'\
 }\
 }\
 }\
}";

I can't use eval or a JS library to parse this into a JavaScript object. All I have available to me are the methods of String, Object, etc.

The result of the parsing should be a JS object whose properties correspond to those of the JSON. The values of the JSON properties will only ever be numbers string or other objects, i.e. no arrays.

I'm really struggling with this, so if anyone could help me get started (or already has a completely solution), it would be much appreciated.

asked Jun 26, 2011 at 15:02
18
  • 2
    This seems a completely pointless task. Even json2.js uses eval. Commented Jun 26, 2011 at 15:07
  • 3
    Uh, it's homework guys. Thats why he can't use the native JSON stuff. Commented Jun 26, 2011 at 15:09
  • 3
    Your example is not valid JSON; the names of object name/value pairs need to be strings. And the backslash-line-break is also not allowed in JavaScript. Commented Jun 26, 2011 at 15:19
  • 2
    @Endophage: You’re wrong. In JSON, the names must be strings (see syntax diagram on json.org or RFC 4627). And a backspace in JavaScript strings must not be followed by a line terminator (see string literals syntax in the ECMAScript specification). Commented Jun 26, 2011 at 15:30
  • 2
    @Endophage: JSON is not JavaScript and vice versa. JSON is a data-interchange format and JavaScript is a programming language. What you are referring to is an object literal notation in JavaScript, but it’s not JSON. jQuery is written in JavaScript but not in JSON. {foo:"bar"} is valid JavaScript but it’s invalid in JSON as foo needs to be quoted as well. Commented Jun 26, 2011 at 17:47

4 Answers 4

4
var json = Function("return {\
foo: {\
 bar: 'something',\
 baz: {\
 jack: 'other',\
 jill: 5\
 },\
 bob: {\
 bill: 'hello',\
 bilbo: 11,\
 baggins: {\
 fizz: 'buzz'\
 }\
 }\
 }\
}")(); // object
answered Jun 26, 2011 at 15:33
Sign up to request clarification or add additional context in comments.

2 Comments

Function accepts any valid JavaScript code but not "just" JSON.
+1 Clever, but of course unsafe and only technically not using eval.
3

Building upon phihag's answer, I just made this up. It might be a start for you.

It does not support:

  • Spaces outside key/value
  • Any of ,{}:" as key/value
  • Arrays
  • No error handling
  • (Probably more - I haven't tested this extensively)

The code:

var json = '{"a":{"b":"test"},"c":123,"d":{"nested":{"key":null}}}';
var split = function(str, delimiter, func) {
 var res = [];
 var before = 0;
 for(var i = 0; i < str.length; i++) {
 if(str[i] === delimiter) {
 if(func(str, i) === true) {
 res.push(str.substring(before, i));
 before = i + 1;
 }
 }
 }
 res.push(str.substring(before));
 return res;
};
var amountbefore = function(str, pos, character) {
 var amount = 0;
 for(var i = 0; i < pos; i++) {
 if(str[i] === character) {
 amount++;
 }
 }
 return amount;
};
var parse = function(obj) {
 var stripped = obj.slice(1, -1);
 var splitted = split(stripped, ",", function(str, i) {
 return amountbefore(str, i, "{") === amountbefore(str, i, "}");
 });
 var res = {};
 if(stripped === "") return res;
 for(var i = 0; i < splitted.length; i++) {
 var spl = split(splitted[i], ":", function(str, i) {
 return amountbefore(str, i, "{") === amountbefore(str, i, "}")
 });
 var val;
 if(spl[1][0] === "n") val = null;
 if(/^\d/.test(spl[1][0])) val = spl[1] - 0;
 if(spl[1][0] === "\"") val = spl[1].slice(1, -1);
 if(spl[1][0] === "{") val = parse(spl[1]);
 res[spl[0].slice(1, -1)] = val;
 }
 return res;
};
parse(json); // parses the JSON string
answered Jun 26, 2011 at 16:04

Comments

2

Luckily, JSON is very easy to parse: Just write parsing functions for each construct. For example, here's one that parses null:

function parseNull(input, position) {
 if (input.substr(position, 4) != "null") throw "Cannot parse as null";
 return {result:null, position: position+4};
}

Implement a similar function for each construct, i.e. parseString, parseArray, parseObject, ... .

Given these functions, write a function parse that skips white-space and decides which of the above functions to call based on the first non white-space character. If that's n, call parseNull, if {, call parseObject etc. . Note that parseArray and parseObject will call parse themselves.

answered Jun 26, 2011 at 15:21

Comments

0

There may be reasons to use a custom JSON parsing method but in case this was what you were looking for...

JavaScript has this all built in for you.

Here's an example:

var json = JSON.parse('{"myKey":"myValue"}');
console.log(json); // {myKey:'myValue'}
answered Nov 8, 2020 at 12:53

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.