[tpm] currency deformatter

Indy Singh indy at indigostar.com
Thu Feb 5 09:19:25 PST 2009


I missed that one.  Here is a more comprehensive solution that deals 
with your test cases.  It guesses the format based on the string, 
however there are cases that are ambiguous.  For a full solution you 
would need to feed in information as to the decimal separator based on 
locale.

Here are the cases that could be a problem:
$123.456 can be considered as 123.456 or 123456.00
$123,456 can be considered as 123.456 or 123456.00

 If I missed anything, I leave it as an exercise to the reader.

currency('$65,345.89');             # case 1
currency('$65.345,89');             # case 2
currency('$24,969.00(txincl.)');    # case 3
currency('$24,969.00*');            # case 4

currency('$123,456,789');           # case 5    whole number
currency('$123.456.789');           # case 6    whole number

currency('$123,456');           # case 7
currency('$123.456');           # case 8


sub currency
{
    my ($x) = @_;
    my ($c) = $x =~ /([0-9\.,]+)/;      # this gets any sequence of 
digits, periods, and commas

    my @p = $c =~ /([,\.])/g;           # get a list of puncuation 
characters (, or .)


    if (@p == 1 && @p[0] eq '.') {
        # string has just one period, assume it is a decimal seperator
    }
    elsif (@p == 1 &&  @p[0] eq ',') {
        # string has just one comma, assume it is a decimal seperator, 
replace with period
        $c =~ s/,/./;
    }
    elsif (@p > 1  &&  @p[@p-1] ne @p[0] && @p[@p-1] eq '.') {
        # case 1, 3, 4
        $c =~ s/,//g;
    }
    elsif (@p > 1 &&  @p[@p-1] ne @p[0] && @p[@p-1] eq ',') {
        # case 2
        $c =~ s/\.//g;
        $c =~ s/,/./;
    }
    else {
        # no puncutation or multiple punctuation characters all the same
        # case 5 or 6
        $c =~ s/\.//g;
        $c =~ s/,//g;
    }
    print "$x -> $c\n";
}






Indy Singh
IndigoSTAR Software -- www.indigostar.com


----- Original Message ----- 
From: "Ilia" <samogon at gmail.com>
To: "Indy Singh" <indy at indigostar.com>; <tpm at to.pm.org>
Sent: Thursday, February 05, 2009 11:28 AM
Subject: Re: [tpm] currency deformatter


> 1..4
> ok 1 - fixup $65,345.89
> not ok 2 - fixup $65.345,89
> #   Failed test 'fixup $65.345,89'
> #   at agency_fix_contract_value.t line 18.
> #          got: '65.34589'
> #     expected: '65345.89'
> ok 3 - fixup $65,345.89(txincl.)
> ok 4 - fixup $65,345.89*
> # Looks like you failed 1 test of 4.
>
>
> On Thu, Feb 5, 2009 at 11:07 AM, Indy Singh <indy at indigostar.com> 
> wrote:
>> The code below will do what you want for your test cases.  I'm not 
>> sure that
>> two lines of code justifies a whole module.
>>
>> $x = '$24,969.00(txincl.)';
>> ($c) = $x =~ /([0-9\.,]+)/;
>> $c =~ s/,//g;
>> print "$x -> $c\n";
>>
>> Indy Singh
>> IndigoSTAR Software -- www.indigostar.com
>>
>>
>> ----- Original Message ----- From: "Ilia" <samogon at gmail.com>
>> To: <tpm at to.pm.org>
>> Sent: Thursday, February 05, 2009 10:29 AM
>> Subject: [tpm] currency deformatter
>>
>>
>>> I can't believe there doesn't seem to be a CPAN module to parse a
>>> currency into a decimal.
>>>
>>> The function I'm looking for should return a decimal based on 
>>> various
>>> input like:
>>> $65,345.89
>>> $65.345,89
>>> $24,969.00(txincl.)
>>> $24,969.00*
>>>
>>> any extraneous data like "(txincl.)" should be removed. any spaces
>>> should be removed.
>>>
>>> Any takers?
>>>
>>> ilia.
>>> _______________________________________________
>>> toronto-pm mailing list
>>> toronto-pm at pm.org
>>> http://mail.pm.org/mailman/listinfo/toronto-pm
>>
>>
>
>
>
> -- 
> Ilia Lobsanov
> Nurey Networks - http://www.nurey.com
> New Ideas for a New Economy
> Python, Perl, Java, Linux & more
> Toronto +1 647 996 9087
> Boston +1 781 328 1162 



More information about the toronto-pm mailing list