Search code examples
lualua-patterns

Is there an efficient and elegant way to truncate number like this in Lua?


What I want to do

What I want to do is really simple. I want use Lua to check lines in a Plist file.

Let's say if a line in Plist, is <integer>-1.00</integer>, I need to cut the .00 off to make it be <integer>-1</integer>.

What I did

I use a function to read the whole file content and do line by line check and replace.

local function doLineClean( cont )
    newcont = ''
    string.gsub( cont, "(.-)\r?\n", function(line)
        if string.match( line, "<integer>.-<%/integer>" ) then
            string.gsub( line, "<.->(.-)<.->", function(v)
            a, b = string.find(v,"%..*")
            if a and b then
                v = string.sub( v, 0, a - 1 )
            end
            line = "\t\t<integer>"..v.."</integer>"
            end  )
        end
        newcont = newcont .. line .. '\n'
    end  )
    return newcont
end

My question

Is there an more efficient and elegant way to do the same job?


Solution

  • First, note that Lua's string patterns are not full regular expressions. They are more limited and less powerful, but usually sufficient (as in this case).

    Why not a far simpler replacement such as the following?

    local s1 = [[
    <integer>3</integer>
    <integer>3.12</integer>
    <integer>-1.00</integer>
    <integer>-1.99</integer>
    <float>3.14</float>
    ]]
    
    local s2 = s1:gsub('(<integer>%-?%d+)%.%d+','%1')
    print(s2)
    --> <integer>3</integer>
    --> <integer>3</integer>
    --> <integer>-1</integer>
    --> <integer>-1</integer>
    --> <float>3.14</float>
    

    This finds:

    1. the text <integer>,
    2. optionally followed by a literal hyphen (%-?)
    3. followed by one or more digit characters (%d+)
    4. followed by a literal period (%.)
    5. followed by one or more digit characters (%d+)

    and replaces it with the first capture (the contents of 1-3, above).

    Note that this will not work if you can have floats without a leading digit (e.g. <integer>.99</integer>) or scientific notation (e.g. <integer>1.34e7</integer>).