Search code examples
stringserializationluavertex

Lua multiple string replacements with string.gsub


Hi there I'm trying to convert vertices stored in a .obj file to a table that can actually be used in lua.

This is what an .obj file looks like:

# Blender v2.77 (sub 0) OBJ File: ''
# www.blender.org
mtllib pyramid.mtl
o Cube
v 1.000000 0.000000 -1.000000
v 1.000000 0.000000 1.000000
v -1.000000 0.000000 1.000000
v -1.000000 0.000000 -1.000000
v -0.000000 2.000000 0.000000
vn 0.0000 -1.0000 0.0000
vn 0.8944 0.4472 0.0000
vn -0.0000 0.4472 0.8944
vn -0.8944 0.4472 -0.0000
vn 0.0000 0.4472 -0.8944
usemtl Material
s off
f 1//1 2//1 3//1 4//1
f 1//2 5//2 2//2
f 2//3 5//3 3//3
f 3//4 5//4 4//4
f 5//5 1//5 4//5

All I need are the 5 lines starting with v to look like this:

Node1= {x=1.000000, y=0.000000, z=-1.000000}
Node2= {x=1.000000, y=0.000000, z=1.000000}
Node3= {x=-1.000000, y=0.000000, z=1.000000}
Node4= {x=-1.000000, y=0.000000, z=-1.000000}
Node5= {x=-0.000000, y=2.000000, z=0.000000}

With the code I wrote, I managed the output to look like this:

Node1= {x=1.000000 0.000000 -1.000000}
Node2= {x=1.000000 0.000000 1.000000}
Node3= {x=-1.000000 0.000000 1.000000}
Node4= {x=-1.000000 0.000000 -1.000000}
Node5= {x=-0.000000 2.000000 0.000000}

Thats my code that is doing the work:

inputFile = io.open("file.txt", "r")
io.input(inputFile)
string = io.read("*all")
io.close(inputFile)

outputFile = io.open("object.lua", "a")
io.output(otputFile)


i = 1
for word in
    string.gmatch(string, " .?%d.%d%d%d%d%d%d .?%d.%d%d%d%d%d%d .?%d.%d%d%d%d%d%d") do
    print(word)
    -- outputFile:write("Node"..i.. "= {" ..word.. "}\n")
    outputFile:write("Node"..i.. "= {" ..string.gsub(word, "(%s)", "x=", 1).. "}\n")
    i = i + 1 
end

First it opens the .obj file and stores everything in "string". Than it creates "object.lua". For every string that is matching this pattern:

1.000000 0.000000 -1.000000

in string, string.gmatch will find it and write it to the output file. But first it has to reformat the string. As you can see I managed to replace the first space (%s) with "x=". Moreover the second space needs to be replaced with ", y=" and the third with ", z=". However I can't see how to use string.gsub in a way that it can do multiple different replacements.

Is this the right way and I'm just doing something wrong? Or is there another way to accomplish this task?


Solution

  • A variation of your overall approach but with the same end result.

    PATTERN = '^v (%S+) (%S+) (%S+)$'
    
    fo = io.open('object.lua','w')
    
    i = 1
    for line in io.lines('file.txt') do
      if line:match(PATTERN) then
        line = line:gsub(PATTERN,'Node'..i..'= {x=%1, y=%2, z=%3}')
        print(line)
        fo:write(line,'\n')
        i = i + 1
      end
    end
    
    fo:close()