Есть ли эффективный и элегантный способ обрезать такие числа в Lua?

Что я хочу сделать

То, что я хочу сделать, действительно просто. Я хочу использовать Lua для проверки строк в файле Plist.

Скажем, если строка в Plist, это <integer>-1.00</integer>Мне нужно отрезать .00 чтобы сделать это <integer>-1</integer>,

Что я сделал

Я использую функцию, чтобы прочитать все содержимое файла и построчно проверить и заменить.

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

Мой вопрос

Есть ли более эффективный и элегантный способ сделать то же самое?

2 ответа

Решение

Во-первых, обратите внимание, что строковые шаблоны Lua не являются полными регулярными выражениями. Они более ограничены и менее мощны, но обычно достаточны (как в этом случае).

Почему бы не намного более простая замена, такая как следующая?

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>

Это находит:

  1. текст <integer>,
  2. необязательно сопровождается буквальным дефисом (%-?)
  3. сопровождаемый одним или несколькими символами (%d+)
  4. с последующим буквальным периодом (%.)
  5. сопровождаемый одним или несколькими символами (%d+)

и заменяет его первым захватом (содержание 1-3, выше).

Обратите внимание, что это не будет работать, если вы можете иметь плавающие числа без начальных цифр (например, <integer>.99</integer>) или научная запись (например, <integer>1.34e7</integer>).

Это должно сделать работу:

s = "<integer>-1.00</integer>"
s:gsub("[.]%d*","")
Другие вопросы по тегам