Finding float numbers

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Finding float numbers

Michael Gerbracht
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.

Reply | Threaded
Open this post in threaded view
|

Re: Finding float numbers

Asko Kauppi

4 in your code is not a float. It's an integer.


Michael Gerbracht kirjoitti 31.3.2009 kello 15:39:

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

Reply | Threaded
Open this post in threaded view
|

Re: Finding float numbers

Michael Gerbracht
In article <[hidden email]>, Asko
Kauppi <[hidden email]> wrote:

> 4 in your code is not a float. It's an integer.

Ok, thats true, but I meant to convert also integer numbers in the same
way. So "4" and "4.2" should be treated the same and both converted into
userdate. Problem is that numbers and userdata can not be compared, so
executing:

print(4 < @"4.2")

gives an error. Therefore I would like to convert all numbers in the
string into floats.

Thanks,
Michael

Reply | Threaded
Open this post in threaded view
|

Re: Finding float numbers

Duncan Cross
In reply to this post by Michael Gerbracht


On Tue, Mar 31, 2009 at 1:39 PM, Michael Gerbracht <[hidden email]> 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
Reply | Threaded
Open this post in threaded view
|

Re: Finding float numbers

Duncan Cross

On Tue, Mar 31, 2009 at 3:43 PM, Duncan Cross <[hidden email]> wrote:


On Tue, Mar 31, 2009 at 1:39 PM, Michael Gerbracht <[hidden email]> 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:

(snip)

--Duncan

Sorry, I just realised a problem with this - it will match something with two decimal points, I should move the second fractional bit inside the previous if block:

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
                local fractional,afterfractional = input:match("^(%.%d+)()",newstart)
                if fractional then
                    buf[#buf+1] = fractional
                    newstart = afterfractional
                end
            end
            buf[#buf+1] = '"'
        end
        start = newstart
    end
    buf[#buf+1] = input:sub(start)
    return table.concat(buf)
end
Reply | Threaded
Open this post in threaded view
|

Finding float numbers

Michael Gerbracht
In article <[hidden email]>,
   Duncan Cross <[hidden email]> wrote:
> Sorry, I just realised a problem with this - it will match something
> with two decimal points, I should move the second fractional bit inside
> the previous if block:
>[program]

Thank you very much, this exactly works in the way I was looking for but I
expected the solution to be simpler and thought that I did not understant
enough of lua's matching syntax. So I guess you are right when you say
that looking into lpeg might be a good idea for similar situations in the
future.

Michael

Reply | Threaded
Open this post in threaded view
|

Re: Finding float numbers

Duncan Cross


On Thu, Apr 2, 2009 at 11:51 AM, Michael Gerbracht <[hidden email]> wrote:
In article <[hidden email]>,
  Duncan Cross <[hidden email]> wrote:
> Sorry, I just realised a problem with this - it will match something
> with two decimal points, I should move the second fractional bit inside
> the previous if block:
>[program]

Thank you very much, this exactly works in the way I was looking for but I
expected the solution to be simpler and thought that I did not understant
enough of lua's matching syntax. So I guess you are right when you say
that looking into lpeg might be a good idea for similar situations in the
future.

Michael


It seems that Lua's string matching has been made pretty underpowered in order to not bloat the string library out of proportion to the rest of the code. It's still useful in a hell of a lot of situations and definitely better than nothing in my opinion, but yeah, do be aware of this. Two subtle features that make this kind of verbose function-based matching possible are the () position captures and the fact that ^ will match the start of the string at the given index if an index is given (which doesn't seem to be standard for regex systems).

-Duncan