0

I have a string that looks like this:

{"name":"Bob","age":20}###{"name":"Brian","age":12}###{"name":"Ryan","age":19}

As you can see, they JSON-like strings are demarcated by ###

My JS Code looks like this:

var data = <above string passed in from a function>
var data_list = data.split('###');          //should return an array with 3 JSON strings

Now I am trying to parse them individually like this:

console.log(JSON.parse(data_list[0]))          // returns [object Object]
console.log(JSON.parse(data_list[1]))          // returns [object Object]

BUT, the last one:

console.log(JSON.parse(data_list[2]))          // Fails               

Error:

Invalid JSON: <json>:28:1 Expected eof but found
}
 ^ in <eval> at line number 28

ALSO: I printed out the contents of each index from the data_list array and they are valid JSON as per jsonlint.com

summerNight
  • 1,446
  • 3
  • 25
  • 52
  • 4
    Is there any (invisible) character after the last closing brace? Try `console.log(JSON.stringify(data_list[2]), JSON.parse(data_list[2].trim()))` – Bergi Jun 29 '17 at 20:11
  • @Bergi: I have these characters: `\u0000\u0000\u0000\u0000`. What's the best way to get rid of them? using the `replace()`? – summerNight Jun 29 '17 at 20:30
  • 1
    `replace`, `trim`, `slice(0, lastIndexOf)` are all valid approaches. Or you find out where they come from and remove them from the source that generated them. – Bergi Jun 29 '17 at 20:40

4 Answers4

0

While the bane of a programmer's existence are quotes, i.e. single vs double and when to use which, the issue here concerns the integrity of the data. One may note that the numbers in the string are unquoted, but that is okay -- still valid JSON; see this discussion. The actual problem stems from the data being tainted with trailing unseen null characters. One may cleanse the data with a simple regex as in the attached example.

var data = '{"name":"Bob","age":20}###{"name":"Brian","age":12}###{"name":"Ryan","age":19}\u0000\u0000\u0000\u0000';

var clean_data = data.replace(/\u0000/g,"");

var data_list = clean_data.split('###');

console.log(JSON.parse(data_list[0]))     
console.log(JSON.parse(data_list[1]))     
console.log(JSON.parse(data_list[2]))

See this discussion

One needs to exercise caution before accepting data as valid regardless as to the source. If a string happens to acquire one or more characters detrimental to JSON, such as null or vertical tab characters, the data becomes compromised. One should assume the data is tainted until proven otherwise. A regex that replaces any occurrences of such characters helps ensure the validity of the data. Whether those characters are represented in unicode or as escape codes is immaterial. The important point is to replace any such occurrences with empty strings; see here.

slevy1
  • 3,797
  • 2
  • 27
  • 33
  • well, in my case I get that string from somewhere else. Please look at bergi's comment above as that relates more to my exact problem and I have `\u0000....` characters at the end of my string – summerNight Jun 29 '17 at 20:37
  • 1
    @summerNight: okay I cleansed the code of the \u0000 characters at the end of your string and the code runs. – slevy1 Jun 29 '17 at 20:50
0

As per Bergi's comments I was able to replace the \u0000\u0000\u0000\u0000 using replace(/\0/g, '') and the JSON is now valid. Thanks Bergi!

summerNight
  • 1,446
  • 3
  • 25
  • 52
0

You could try this code, to transform that string into an array of JSON objects.

var array = [];
var uniqueString = '[' + data.replaceAll('###', ', ') + ']';
array = JSON.parse(uniqueString);

Now 'array' is an array of JSON parsed object, so you should be able to obtain something like this.

array[0] will be '{"name": "Bob", "age": 20}'

Gozus19
  • 165
  • 19
0

please check your data string, it may have some invisible character as @Bergi said.

I already check by pasting your string as below.

var sample = '{"name":"Bob","age":20}###{"name":"Brian","age":12}###{"name":"Ryan","age":19}';
var data_str = sample.split('###');
console.log(JSON.parse(data_str[0]));
console.log(JSON.parse(data_str[1]));
console.log(JSON.parse(data_str[2]));

Output Was on console::

Object {name: "Bob", age: 20}
VM981:4 Object {name: "Brian", age: 12}
VM981:5 Object {name: "Ryan", age: 19}
Azeem Chauhan
  • 407
  • 5
  • 8