Fixing a json file, need help with patterns

today I got a json file with a lot of keys and values. Peoblem: there are no quotes around the keys, and no commas at the end of lines. So json.decode returns nil instead of a table. (I think it was beautified lol)

My quest to fixing it begins. I dont know anything about strings. Somehow, i managed this code, whichis run a while loop through allcharacters, and when you find an opening bracket, then use string find to look for a closing bracket, and when you find that closing bracket, start a nested while loop to go through everything inbetween the brackets, and FIX. THAT. FILE.

Problem is i dont know how to use patterns.

function setup()
    b = [[
    {
    example: "string"
    bad line: "good string"
    }
    {
    apple: "red"
    banana: "yellow"
    }
    ]]
end
function fix(s);
    local data, new = readText(s), "";
    local x,k,e = 1;
    while x < string.len(s) + 1 do
        if string.byte(s, x) == 123 then
            --e = string.find(s, 125, x)
            --125 is the byte value of }, but its not that pattern
            --which i find really dumb
            local x2 = x
            while x2 < e do
                --here we add quotes for keys without quotes
                --and put commas on the end of newlines
                --but how do I do that?
                x2 = x2 + 1
            end
        end
        --the first while loop will run a bit wasteful at this point until it finds the next {
        x = x+1
    end
    return new;
end;

@xThomas Can you show what a few lines of the file looks like and then what you want those lines to look like. It’s easier to write code when you have something to test with and know what the results should look like.

Try using string.gsub. Here is some code that will fix the string you provided (assuming there are no spaces at the start or end of names:

b = string.gsub(b,'(%w[%w ]+%w) ?: ?"([^"]-)"',function(v,w)
        return '"'..v..'":'..'"'..w..'"'
    end)

A detailed walkthrough:

  1. string.gsub takes a string as the first argument, and matches patterns in it given by the second argument, then replaces them with ani other pattern or a function (in my case).
  2. The pattern is composed of “captures”, which grab parts of the string and pass them to the function, in order.
  3. They look like this: (abc) — whenever gsub sees “abc”, it will pass it into the function as a capture.
  4. %w matches any word character
  5. [%w ] matches any word character or a space.
  6. + grabs multiple matches of the previous character.
  7. ?: ? matches a colon “:” with an optional “?” space before and after it.
  8. Now we look for a string surrounded by quotes, and capture it. This part is a little complicated, so I’ll skip it.
  9. Pass the first capture (the first group in parentheses) and the second capture (the second group, without quotes)
  10. Return the new version of your string, nicely formatted.

If my explanation wasn’t enough, and even if it was, I strongly encourage you to read the documentation. There is so much you can learn there if you just read carefully and be patient.

regexr.com has some pretty good tutorials about regex, which has syntax similar to lua’s patterns. You can also start your learning from there.

Thx. Not totally there yet, but thats a big help.

Edit. @em2 @dave1707 In this example. It prints the first object’s values, but not the second.

Name Apple
Color red

Why? How do I make it do all?

A thought I have is that I want to make a table of tables, the objects being the sub tables. But in this case, i believe it is only sending the first object instead of a table of objects

-- Json Two

a = [[{
    "Name": "Apple",
    "Color": "red",
}
{
    "Name": "Banana",
    "Color": "green",
}]]
a = json.decode(a)
for k,v in pairs(a) do
    print(k,v)
    
end




Your table is missing a comma (have you read JSON documentation?) and it needs [] surrounding it:

a = [[
--> one bracket goes here ( [ )
{
    "Name": "Apple",
    "Color": "red",
} --> Comma should be here
{
    "Name": "Banana",
    "Color": "green",
}
--> closing bracket ( ] )
]]