lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]




On Tue, Mar 31, 2009 at 1:39 PM, Michael Gerbracht <smartmails@arcor.de> wrote:
I need to convert float numbers into a string in a certain way[1]. The
original string looks like:

'var*4+5.2E-7-var2'

I need to convert it into:

'var*@"4"+@"5.2E-7"-var2'

so all floating point numbers n need to be replaces by @"n". Can you
suggest a good way to do that?

My main problem is to define a pattern for searching that matches all
floating point numbers, but not e.g. '4+5.2' in the above example.

Is it possible with lua or do I need the lpeg extension?

Thank you very much!
Michael

[1] I need to do that because I use RiscLua which supports floating point
numbers only as userdata.


You've definitely hit the limits of what Lua's standard string pattern matching can gracefully handle. It's still possible with a big function like this, but it's clear that if it was any more complicated, switching to something like LPEG would be the only sensible choice:

function process_floats(input)
    local buf = {}
    local start = 1
    while (start <= #input) do
        local before,int,newstart = input:match("^(.-)(%d+)()",start)
        if not int then
            break
        end
        if before:match("%w$") then
            buf[#buf+1] = before .. int
        else
            buf[#buf+1] = before .. '@"' .. int
            local fractional,afterfractional = input:match("^(%.%d+)()",newstart)
            if fractional then
                buf[#buf+1] = fractional
                newstart = afterfractional
            end
            local exponentint,afterexponentint = input:match("^([Ee]%-?%d+)()",newstart)
            if exponentint then
                buf[#buf+1] = exponentint
                newstart = afterexponentint
            end
            local fractional,afterfractional = input:match("^(%.%d+)()",newstart)
            if fractional then
                buf[#buf+1] = fractional
                newstart = afterfractional
            end
            buf[#buf+1] = '"'
        end
        start = newstart
    end
    buf[#buf+1] = input:sub(start)
    return table.concat(buf)
end

--Duncan