1

I have read a file with a JSON appearance, and the format is similar to the following:

{
    varParent1: {
        var1: true,
        var2: "this is a string",
        var3: 0,
        var4: "another string"
    },
    varParent2:{
        var1: false,
        var2: 0,
        var3: 92,
        var4: "string here",
        var5: "string2 here"
    }
}

I have this code in a variable, but I can't edit the file, so I should work only with the variable.

As everybody can see, it is not a valid format JSON, so I am not being able to parse it. I need to format it to something like this:

{
    "varParent1": {
        "var1": true,
        "var2": "this is a string",
        "var3": 0,
        "var4": "another string"
    },
    "varParent2":{
        "var1": false,
        "var2": 0,
        "var3": 92,
        "var4": "string here",
        "var5": "string2 here"
    }
}

I have thought about the logic and I have a conclusion (I think it's fine): I have to add '"' to the start and end of every line and between ":" too. But i'm not able to do that with regex.

Is there an easier way?

Víctor López
  • 819
  • 1
  • 7
  • 19
  • 1
    @George — How do you parse the data in the file into a JavaScript variable so you can use JSON.stringify? – Quentin Jul 28 '17 at 09:16
  • @Quentin My bad, I didn't read the question correctly. Would it not just be easier to change the data in the file itself to be JSON rather than mess around with it in code? As the only way I can see of parsing that data is with `eval()` – George Jul 28 '17 at 09:18
  • @George First of all, thanks for the answer. I can't edit the file, because it's on a server and I only have read access. That's the main reason I'm trying to solve it with regex. – Víctor López Jul 28 '17 at 09:23
  • @H77 — When the file is in a variable it will be a string, not an object. JSON.stringify will just create a JSON representation of that string (i.e. replace new lines with `\n`, put a slash before each quote and wrap it in quotes). – Quentin Jul 28 '17 at 09:24
  • 2
    @H77 — It's not JSON! The question states that quite clearly. Parsing it will throw an error. – Quentin Jul 28 '17 at 09:24
  • @H77 I have the string loaded in a variable, but as I said in the question, it's not a valid JSON. When I try JSON.parse, It says "Is not a valid JSON" – Víctor López Jul 28 '17 at 09:26
  • @Quentin You got it. It's as you say. I think you are the only one that understand my question. Maybe I have not expressed myself correctly. – Víctor López Jul 28 '17 at 09:27
  • @VíctorLópez Might want to put the first code block to be like `var myFile = "{ etc }"` so people can see it's a string of an object and not just an object, might clear things up. But I get what your question is now – George Jul 28 '17 at 09:28
  • how trusted is the data? there's always `eval` – Jaromanda X Jul 28 '17 at 09:35
  • Possible duplicate of [convert invalid JSON string to JSON](https://stackoverflow.com/questions/24462658/convert-invalid-json-string-to-json) – H77 Jul 28 '17 at 09:44
  • @H77 the problem with that answer is that it would convert `true` into `"true"` and `0` into `"0"` – George Jul 28 '17 at 09:52

3 Answers3

0

This:

var json = text.replace(/([A-Za-z0-9]+)\:/g, "\"$1\":");

works with your example, however if a string value contains a colon, you're in trouble.

for a more general solution, you can start by separating the string literals from the rest, then apply the replace on the non-strings, then concatenate again:

        var nonStrings = [], strings = [];
        var re = /"(?:[^"\\]|\\.)*"/g;
        var rs;
        var start = 0;
        while (rs = re.exec(text)) {
            var end = rs.index;
            nonStrings.push(text.substring(start,end));
            strings.push(rs[0]);
            start = end + rs[0].length;
        }
        nonStrings.push(text.substring(start));
        console.log(nonStrings);
        console.log(strings);
        for (var i = 0; i < nonStrings.length; ++i) {
            nonStrings[i] = nonStrings[i].replace(/([A-Za-z0-9]+)\:/g, "\"$1\":");
        }
        var json = nonStrings[0];
        for (var i = 0; i < strings.length; ++i) {
            json += strings[i] + nonStrings[i+1];
        }
        console.log(json);

UPDATE:

You can actually simplify this by merging the different passes:

        var re = /"(?:[^"\\]|\\.)*"/g;
        var rs;
        var start = 0;
        var json = "";
        while (rs = re.exec(text)) {
            var end = rs.index;
            json += text.substring(start,end).replace(/([A-Za-z0-9]+)\:/g, "\"$1\":") + rs[0];
            start = end + rs[0].length;
        }
        json += text.substring(start).replace(/([A-Za-z0-9]+)\:/g, "\"$1\":");
        console.log(json);
Maurice Perry
  • 9,261
  • 2
  • 12
  • 24
-1
    JSON.stringify({
            varParent1: {
                    var1: true,
                    var2: "this is a string",
                    var3: 0,
                    var4: "another string"
            },
            varParent2:{
                    var1: false,
                    var2: 0,
                    var3: 92,
                    var4: "string here",
                    var5: "string2 here"
            }
    })

the output will be the json string. with JSON.parse function you can create a javascript object from json string

lacexd
  • 903
  • 1
  • 7
  • 22
  • Is not a valid json, so you cant use JSON.parse. – Víctor López Jul 28 '17 at 09:16
  • 1
    @VíctorLópez the result of JSON.stringify is valid JSON, – Maurice Perry Jul 28 '17 at 09:19
  • 2
    The question is asking about reading the file with JavaScript and then parsing the data in it. Your proposal appears to be "Edit the file manually to turn it into a JavaScript program and then execute that program" which doesn't really seem to have much to do with that. – Quentin Jul 28 '17 at 09:20
-1

Might not be the best way around it but you can create a script element and assign it to a variable in there for use.

var data = '{varParent1: {var1: true, var2: "this is a string", var3: 0, var4: "another string"}, varParent2:{ var1: false, var2: 0, var3: 92, var4: "string here", var5: "string2 here"}}'

var script = document.createElement("script");
script.innerText = "var test = "+data;
document.body.append(script);

console.log(test.varParent1.var2);
console.log(test);

Although you have said

I can't edit the file, because it's on a server and I only have read access.

I would request for the file to be changed to a format that makes it easier to transfer be it XML or JSON.

George
  • 6,630
  • 2
  • 29
  • 36