3

Let's say I receive this string from a socket server (which I cannot control):

{"data":{"time":"2016-08-08T15:13:19.605234Z","x":20,"y":30}}{"data":{"time":"2016-08-08T15:13:19.609522Z","x":30,"y":40}} 

I cannot use JSON.parse since it contains 2 Json string so how can I split into

var jsonString1 = {"data":{"time":"2016-08-08T15:13:19.605234Z","x":20,"y":30}}

and

var jsonString2 = {"data":{"time":"2016-08-08T15:13:19.609522Z","x":30,"y":40}} 

Note: I may have 1 to n Json strings concatenated in fact

user310291
  • 36,946
  • 82
  • 271
  • 487
  • So you have an array of jsons, to start with. You should then be parsing the array of jsons first, and then each json separately.This is how I do it with Newtonsoft's library for .net. – Veverke Aug 08 '16 at 15:25
  • I would loop through each character of the string, count the number of '{' and '}' characters. Once the amount of '{' are equal to the amount of '}' you know your first JSON string has ended. Except ofcourse when you start the loop and the amount for both of them is 0 – Alain Stoffels Aug 08 '16 at 15:26
  • 2
    How about splitting the original string using `split("}{")` ? – Rajaprabhu Aravindasamy Aug 08 '16 at 15:26

3 Answers3

9

You could just do:

var data = '{"data":{"time":"2016-08-08T15:13:19.605234Z","x":20,"y":30}}{"data":{"time":"2016-08-08T15:13:19.609522Z","x":30,"y":40}}';

var sanitized = '[' + data.replace(/}{/g, '},{') + ']';
var res = JSON.parse(sanitized);

console.log(res);

However, this will fail if one of the objects contains the }{ pattern in a string.

Arnauld
  • 5,847
  • 2
  • 15
  • 32
  • It works but I'd like to print x, y : see https://jsfiddle.net/ys6j038q/ – user310291 Aug 08 '16 at 16:45
  • I ask complementary question here: http://stackoverflow.com/questions/38834601/how-to-get-x-y-from-nest-object – user310291 Aug 08 '16 at 16:49
  • What you get here is an array of objects. If you want to access the `x` property of the second object, you'd have to do `res[1].data.x`. – Arnauld Aug 08 '16 at 16:55
4

You can split them by the occurrence of } followed directly by { (ignoring whitespace).

var parts = str.split(/\}\s*\{/g);
for(var i = 0; i < parts.length; i++) {
  var part = parts[i].trim();

  if(part[0] !== '{') part = '{' + part;
  if(part[part.length-1] !== '}') part += '}';

  var json = JSON.parse(part);
}
micah
  • 7,596
  • 10
  • 49
  • 90
  • But each json contains nested objects. What if data is : {} ? – Veverke Aug 08 '16 at 15:27
  • @Veverke Those objects would be split by a comma. – micah Aug 08 '16 at 15:29
  • I was trying something less hard-wired. If this solves the issue, however, it's the answer :) – Veverke Aug 08 '16 at 15:30
  • @Veverke JSON doesn't allow an unescaped `}{` anywhere outside of strings. [The spec](http://www.json.org/) is very concise, so you can check. – ssube Aug 08 '16 at 15:30
  • Why anyway the source of this string does not return an array of jsons ? I would expect a comma separating each distinct js object enclosing the "data" property. If he has control over the source, I would fix this, and make things more intuitive. – Veverke Aug 08 '16 at 15:32
1

Just split when /\}\s*\{/g and pass a value to fill to the Array.prototype.reduce function.

var str = '{"data":{"time":"2016-08-08T15:13:19.605234Z","x":20,"y":30}}{"data":{"time":"2016-08-08T15:13:19.609522Z","x":30,"y":40}}'

var data = (function(input) {
  let odd = true;
  
  return input.split(/\}\s*\{/g).reduce(function(res, part, i) {
    if(odd) {
      part += "}";
    } else {
      part = "{" + part;
    }
    
    odd = !odd;
    
    res[i] = JSON.parse(part);
    
    return res;
  }, {});
})(str)

console.log("data:", data);
Hitmands
  • 13,491
  • 4
  • 34
  • 69