# [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

```