4

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?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Tim
  • 2,121
  • 2
  • 20
  • 30
  • 1
    To be clear, you want not just `-1.00` to be `-1`, but all floating point numbers inside of `` element to be truncated? What if it is `-1.99`? – Phrogz Jan 02 '14 at 03:29
  • @Phrogz yes, truncate all floats, `-1.99` should be `-1` – Tim Jan 02 '14 at 03:31

2 Answers2

7

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

Phrogz
  • 296,393
  • 112
  • 651
  • 745
-2

That should do the job:

s = "<integer>-1.00</integer>"
s:gsub("[.]%d*","")
hendrik
  • 1,902
  • 16
  • 14
  • -1 Presumably this file may have decimal values in other locations that should not be touched, e.g. `3.14` or `1.2.3`. Further, what you have here will also remove raw periods (e.g. `"Hello. Bye!"` will become `"Hello Bye!"`). – Phrogz Jan 02 '14 at 03:43
  • Well the solution is based on the given input. I don't know what other content is in the file. The solution need to be modified in case ... – hendrik Jan 02 '14 at 03:50