Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Fixing a json file, need help with patterns

edited September 2017 in Questions Posts: 121

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;

Comments

  • dave1707dave1707 Mod
    Posts: 7,553

    @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.

  • em2em2
    Posts: 194

    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.

  • em2em2
    Posts: 194

    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.

  • edited September 2017 Posts: 121

    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
    
    
    
    
    
  • em2em2
    edited September 2017 Posts: 194

    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 ( ] )
    ]]
    
Sign In or Register to comment.