4

I am having trouble with parsing a non-json object string to an actual object in javascript

the example string looks like:

let objString = '{ one: [1, 2, 3], num: 1 }';

what I want it to look like is

obj = { one: [1, 2, 3], num: 1 };

So far I have tried:

  • JSON.stringify then JSON.parse
  • JSON.parse
  • eval

None of these work for rather obvious reasons but I am stuck at how to accomplish this, this is for a class I am writing to run and evaluate code, below is a snippet of the method in question.

compare() {
  const { testCaseInfo, stdout } = this;
  const expected = testCaseInfo.expected;
  if (this.err || stdout.length < 1) { return false };

  let parsedAnswer = stdout;
  parsedAnswer = parsedAnswer.split('\n').join('');
  
  /* Need help here, some edge case of Obj strings */
  if (parsedAnswer.indexOf('{')) {

  }
  // This works for everything else
  parsedAnswer = JSON.parse(parsedAnswer);

  this.output = parsedAnswer;
  
  return _.isEqual(parsedAnswer, expected);
}
7
  • This is a very X/Y problem. Possible, but I'd really really suggest considering an alternative method if feasible Commented Apr 7, 2021 at 2:36
  • Try replacing all ' to " like objectString.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": ');
    – fortunee
    Commented Apr 7, 2021 at 2:37
  • Do you have any control over how objString is generated? JSON.parse('{ "one": [1, 2, 3], "num": 1 }') works with quotes around the keys. If not, you may need to look at sanitizing your JSON. stackoverflow.com/questions/9637517/…
    – wahoowa
    Commented Apr 7, 2021 at 2:37
  • @wahoowa the raw text is actually collected from the stdout of executing a file, so it has already comes as a string and not in JSON format. :(
    – user13291588
    Commented Apr 7, 2021 at 2:38
  • @fortunee thank you for the idea, didnt work sadly.
    – user13291588
    Commented Apr 7, 2021 at 2:40

6 Answers 6

5

A bit late to the party but I've just run into this myself so I thought I would give it a quick search and this thread popped up. Anyway, I would rather use this:

let obj = new Function("return " + objString + ";")();
1

I've found a really cheeky way to do it

let obj = {}
eval("obj =" + '{ one: [1, 2, 3], num: 1 }')
0
1

Wrap it in parentheses.

let objString = '{ one: [1, 2, 3], num: 1 }';
let obj = eval('(' + objString + ')');

Needless to say though, you should only ever eval things from trusted sources.

0
1

Since using eval() is security risk. I would suggest you to try converting your string to a parsable JSON string then use JSON.parse() to parse.

const keyFinderRegEX = /([{,]\s*)(\S+)\s*(:)/mg;
const convertedJSONString = '{ one: [1, 2, 3], num: 1 }'.replace(keyFinderRegEX, '$1"$2"$3');
const parsedObj = JSON.parse(convertedJSONString);

    console.log(parsedObj)

1

In order to avoid using eval, you can check if your input strings always comply to JSON5 format. It is less strict than traditional JSON and allows, e. g., not using quotes for key names definition, like in ECMAScript objects.

In order to parse JSON5 strings, use JSON5 npm package. Its API is the same as in the standard JSON object: you can just import it, write JSON5.parse(objString) and that's it.

-1

Turn your String into this format below and it should parse properly using JSON.parse()

let objString = '{ "one": [1, 2, 3], "num": 1 }';

console.log(JSON.parse(objString));

3
  • How exactly would I go about doing this, I thought of this as an approach as but seems extremely difficult to actually develop a function to achieve this...
    – user13291588
    Commented Apr 7, 2021 at 2:37
  • You could try something like this JSON.parse('{ one: [1, 2, 3], num: 1 }'.replace(/([{,]\s*)(\S+)\s*(:)/mg, '$1"$2"$3'))
    – Ravikumar
    Commented Apr 7, 2021 at 4:33
  • You didn't answer the actual question. The question was how to parse data that was not in a JSON format. Using data that is JSON format is pointedly not what was asked. Commented Jan 29 at 21:50