Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to strip json comments in javascript

How to strip json comments in javascript ? I think a regex will be a concise way.

{
    "filed": { // comments
         "n": 1 /* multi-line ...
                                 comments */
    },
    "field2": " // comments in string , /* here */ "
}

should work on the above example.
Note: the comments in the string should not be removed.

Update: i know that comments in json are not valid, but for simplicity i want to have them and then remove them, i see a lot of tools support parsing jsons which have comments.

Update 2: the above example itself is a string, i didn't explain that (sorry), and now see some answers thinking its a js code.

Update 3: i again forgot to put keynames in double quotes, updated the question.

like image 456
Amin Roosta Avatar asked Nov 02 '15 17:11

Amin Roosta


3 Answers

While commenting in JSON is not a standard practice, in some cases it could be useful. For this purpose I wrote small package for nodejs: json-easy-strip

Your JSON file could contain any valid JS comments:

{
    /*
     * Sweet section
     */
    "fruit": "Watermelon", // Yes, watermelons is sweet!
    "dessert": /* Yummy! */ "Cheesecake",
    // And finally
    "drink": "Milkshake - /* strawberry */ or // chocolate!" // Mmm...
}

And here is how we strip it:

//
// Our JSON string
let jsonString = `{
    /*
     * Sweet section
     */
    "fruit": "Watermelon", // Yes, watermelons is sweet!
    "dessert": /* Yummy! */ "Cheesecake",
    // And finally
    "drink": "Milkshake - /* strawberry */ or // chocolate!" // Mmm...
}`;

//
// One-liner comment stripper
jsonString = jsonString.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (m, g) => g ? "" : m);

//
// Parse jsonString and print result
console.log(JSON.parse(jsonString));

//
// Result
//  {
//    fruit: "Watermelon",
//    dessert: "Cheesecake",
//    drink: "Milkshake - /* strawberry */ or // chocolate!"
//  }
like image 181
tarkh Avatar answered Sep 29 '22 09:09

tarkh


One simple way is to run JSON.stringify and then JSON.parse and voila it's clean.

like image 36
Olavi Sau Avatar answered Sep 29 '22 09:09

Olavi Sau


Let the javascript parser do it:

a = {
    filed: { // comments
         n: 1 /* multi-line ...
                                 comments */
    },
    field2: " // comments in string , /* here */ "
}
a.toSource()
/*
({filed:{n:1}, field2:" // comments in string , /* here */ "})
*/

You could do it with a string (according to the edited question) the very same way:

a =   'a = {\r\n  filed: { // comments  n: 1 \r\n/* multi-line ...  comments */\r\n},\r\n'
    + 'field2: " // comments in string , /* here */ "\r\n}'
eval(a).toSource().toString();

But it doesn't seem to work with chrome? Oh, forgot, it is FF only, sorry (in Javascript version 3).

I found a replacement at https://gist.github.com/archan937/1961799 so the following works in most of the rest of the browsers, too.

function inspect(object) {
  switch (typeof(object)) {
  case "undefined":
    return "undefined";
  case "string":
    return "\"" + object.replace(/\n/g, "\\n").replace(/\"/g, "\\\"") + "\"";
  case "object":
    if (object == null) {
      return "null";
    }
    var a = [];
    if (object instanceof Array) {
      for (var i in object) {
        a.push(inspect(object[i]));
      };
      return "[" + a.join(", ") + "]";
    } else {
      for (var key in object) {
        if (object.hasOwnProperty(key)) {
          a.push(key + ": " + inspect(object[key]));
        }
      };
      return "{" + a.join(", ") + "}";
    }
  default:
    return object.toString();
  }
};

a = 'a = {\r\n  filed: { // comments  n: 1 \r\n/* multi-line ...  comments */\r\n},\r\n'
    + 'field2: " // comments in string , /* here */ "\r\n}'

alert(inspect(eval(a)));
like image 24
deamentiaemundi Avatar answered Sep 29 '22 11:09

deamentiaemundi