42

In order to install an external extension into Google Chrome browser, I try to update a Chrome external extension JSON file. Using Json.NET it seems to be easy:

string fileName = "..."; // Path to a Chrome external extension JSON file

string externalExtensionsJson = File.ReadAllText(fileName);

JObject externalExtensions = JObject.Parse(externalExtensionsJson);


but I get a Newtonsoft.Json.JsonReaderException saying:

"Error parsing comment. Expected: *, got /. Path '', line 1, position 1."


when calling JObject.Parse because this file contains:

// This JSON file will contain a list of extensions that will be included
// in the installer.

{
}

And comments are not part of JSON (as seen in How do I add comments to Json.NET output?).

I know I can remove comments with a regular expression (Regular expression to remove JavaScript double slash (//) style comments), but I need to rewrite JSON into the file after modification and keeping comment can be a good thing.

Is there a way to read JSON content with comments without removing them and be able to rewrite them?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
MuiBienCarlota
  • 2,157
  • 1
  • 25
  • 32

3 Answers3

54

Json.NET only supports reading multi-line JavaScript comments, i.e. /* commment */

Update: Json.NET 6.0 supports single line comments

James Newton-King
  • 44,416
  • 22
  • 106
  • 128
  • 2
    Thanks but I have no choice: Google Chrome provides a file named "external_extensions.json" containing single line comments and I must complete it. More generally, Json is often used as configuration file where comments (single and/or multi lines) can be added by users. We have no choice: we can be faced with the need to read each comment (and ideally rewrite it). And I liked to be able to use Json.Net to do it. Do you think it can be a possible evolution? – MuiBienCarlota Apr 26 '12 at 08:30
  • Replacing with regex was not a completely satisfactory solution. Taking it into account into Json.Net was what I was hoping. Thanks! – MuiBienCarlota Aug 04 '14 at 10:04
  • 1
    Damn. Most justified un-accept I've had so far. Curse you! :) – Basic Aug 04 '14 at 17:34
  • 1
    @tofutim: They're safe from crude "chomp"-like minifiers – Mark K Cowan Feb 28 '15 at 14:50
  • I still get errors with comments though. Like this `Error reading JObject from JsonReader. Current JsonReader item is not an object: Comment` – Joseph Kingry Aug 07 '15 at 20:39
4

If you are stuck with JavaScriptSerializer (from the System.Web.Script.Serialization namespace), I have found that this works good enough...

private static string StripComments(string input)
{
    // JavaScriptSerializer doesn't accept commented-out JSON,
    // so we'll strip them out ourselves;
    // NOTE: for safety and simplicity, we only support comments on their own lines,
    // not sharing lines with real JSON

    input = Regex.Replace(input, @"^\s*//.*$", "", RegexOptions.Multiline);  // removes comments like this
    input = Regex.Replace(input, @"^\s*/\*(\s|\S)*?\*/\s*$", "", RegexOptions.Multiline); /* comments like this */

    return input;
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
shane-o
  • 49
  • 3
  • I haven't tested this, but it looks to me like these only remove comments that start and end on their own line. you can remove the `^\s*` prefix from both (Multiline may also be unnecessary on the first regex) to remove comments starting on the same line as a value (e.g. `"Prop": "Value" // This is a property` ), and you can remove the `\s*$` suffix from the second to allow a comment to end on a line with data (e.g. `/* Setting */ "Prop": "Value"`). These, however, will only work correctly if no strings in the JSON data contain `//` or `/* */` - (Note: this is all from freehand/manual reading) – TheXenocide Jun 24 '20 at 15:59
3

You could always convert single-line comments to multi-line comment syntax before parsing...

Something like replace...

.*//.*\n

with

$1/*$2*/

...

Regex.Replace(subjectString, ".*//.*$", "$1/*$2*/");
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Basic
  • 25,223
  • 23
  • 108
  • 188
  • 2
    I think your regex will match too much. Consider valid json values that have "//" in them: `{url: 'http://www.forever21.com/Product/Product.aspx?br=f21&category=dress&productid=2000062214', photo: 'http://www.forever21.com/images/default_330/00062214-02.jpg'}` – Scott Roberts Apr 10 '14 at 21:18
  • 1
    @ScottRoberts True. Unfortunately, we're edging into trying to parse json with regex. And that way lies madness. That said, if someone with better regex skills can fix it, please do. – Basic Apr 10 '14 at 23:47
  • 1
    I just got bit by http:// in config, after rolling my own regex. Wound up here, among my fellow Damned. :-) – david van brink Jun 06 '14 at 19:03
  • Though I confess I just amended the regex to be `//[^'"]*$` and told my friends, no single or double quotes in your comments. Madness exactly. – david van brink Jun 06 '14 at 19:19