Javascript Convert String to Array of Objects

nelsonic picture nelsonic · Apr 25, 2013 · Viewed 17.3k times · Source

I have a NodeJS App that accepts a a string (uploaded input!) I have No Control over the input I am merely building a REST Service to Processes the data.

That string is meant to be an Array of JSON Objects that I can then loop through to extract each element ...

I'm receiving the following (as a string):

[
  {Name: 'Jane',
       Id: '005b0000000MGa7AAG'},
  {Name: 'Tom',
       Id: '005b0000000MGa7AAF'}
]

When I try to JSON.parse this I get

SyntaxError: Unexpected token N

Understandably so, because I know this is Invalid JSON

whereas This next string is valid JSON and passes http://jsonlint.com/:

[
    {"Name": "Jack",
        "Id": "005b0000000MGa7AAA"},
    {"Name": "Jill",
        "Id": "005b0000000MGa7AAB"}
]

My question is: How can I accept the first input and parse it to allow:

parsed[0]['Name'] == 'Jane'
>> true

My first instinct is to string replace the keys (e.g. Name to "Name") and then try parsing it. But if anyone else has a solution, I'd be grateful.

Answer

musefan picture musefan · Apr 25, 2013

You can do this with a bit of Regex replacing:

var json = "[ {Name: 'Jane', Id: '005b0000000MGa7AAG'}, {Name: 'Tom', Id: '005b0000000MGa7AAF'} ]";

var newJson = json.replace(/([a-zA-Z0-9]+?):/g, '"$1":');
newJson = newJson.replace(/'/g, '"');

var data = JSON.parse(newJson);

alert(data[0]["Name"]);

First of all we wrap the propertie names with quotes, then we replace the single-quotes with double-quotes. This is enough to make it valid JSON which can then be parsed.

Here is a working example


NOTE: Using RegEx in general for things like this is not ideal, and this solution will only work under specific circumstances (like this example). As mentioned in comments, one problem would be if the data values contained a colon :

With that in mind, this is a more reliable solution:

var json = $("div").html();

var newJson = json.replace(/'/g, '"');

newJson = newJson.replace(/([^"]+)|("[^"]+")/g, function($0, $1, $2) {
    if ($1) {
        return $1.replace(/([a-zA-Z0-9]+?):/g, '"$1":');
    } else {
        return $2; 
    } 
});

var data = JSON.parse(newJson);
alert(data[0]["Name"]);

This will match any variables (alphanumeric) that end with a colon :, but will ingore any matches that are found between quotes (i.e. data string values)

Here is an example