[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Currency formatting with regexp

Jim Van Fleet

2/11/2005 6:05:00 PM

Hi, all, this is my first post to Ruby-talk, so please be kind-- if
that's not your natural disposition.

I'm looking to work up some code that turns floats into string-based
currency values.

I've got an implementation working that's pretty ungodly. It looks a
lot like I would program it in Java. Naturally, once I finished, I
found some Perl suggestion that looks like this:

sub commify {
my $text = reverse $_[0];
$text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
return scalar reverse $text;
}

I am a regexp noob. I experimented with using gsub and this regular
expression, but I can't seem to get anywhere. The closest I've come
replaces the first comma but then eliminates the rest of the number.

Can someone help me figure out what's going on-- or point me to where
this is already available in Ruby? (Pickaxe II references neither money
nor currency, and I don't really want to install extensions just for
this functionality.)

Thanks so much,

Jim


8 Answers

James Gray

2/11/2005 6:25:00 PM

0

On Feb 11, 2005, at 12:04 PM, Jim Van Fleet wrote:

> sub commify {
> my $text = reverse $_[0];
> $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
> return scalar reverse $text;
> }

Here's a direct Ruby translation:

def commify( number )
text = number.to_s.reverse
text.gsub!(/(\d\d\d)(?=\d)(?!\d*\.)/, '\1,')
text.reverse
end

Hope that helps.

James Edward Gray II



Jim Van Fleet

2/11/2005 7:46:00 PM

0

James Edward Gray II wrote:
> On Feb 11, 2005, at 12:04 PM, Jim Van Fleet wrote:
>
>
> Here's a direct Ruby translation:
>
> def commify( number )
> text = number.to_s.reverse
> text.gsub!(/(\d\d\d)(?=\d)(?!\d*\.)/, '\1,')
> text.reverse
> end
>
> Hope that helps.

It sure did, and cut my LOC count in half.

What does \1 signify, exactly? Is this the active matched section of
the source string at the time?

Cheers,

Jim


James Gray

2/11/2005 8:06:00 PM

0

On Feb 11, 2005, at 1:46 PM, Jim Van Fleet wrote:

> It sure did, and cut my LOC count in half.

Good news.

> What does \1 signify, exactly? Is this the active matched section of
> the source string at the time?

In a replacement string, \N is equivalent to Perl's $N variables.
Outside a replacement string, you can $N variables directly. You can
also use them in the block form of gsub().

Hope that clears it up.

James Edward Gray II



Austin Ziegler

2/11/2005 8:17:00 PM

0

On Sat, 12 Feb 2005 03:04:35 +0900, Jim Van Fleet <jim@jimvanfleet.com> wrote:
> I'm looking to work up some code that turns floats into string-based
> currency values.

Might I suggest looking at Gavin Sinclair's "extensions" package? This
has some code that I wrote and released under an MIT-style licence to
format numbers with commas and has a *lot* of different formatting
capabilities.

-austin
--
Austin Ziegler * halostatue@gmail.com
* Alternate: austin@halostatue.ca


Mark Hubbart

2/12/2005 12:33:00 AM

0

On Sat, 12 Feb 2005 03:25:20 +0900, James Edward Gray II
<james@grayproductions.net> wrote:
> On Feb 11, 2005, at 12:04 PM, Jim Van Fleet wrote:
>
> > sub commify {
> > my $text = reverse $_[0];
> > $text =~ s/(\d\d\d)(?=\d)(?!\d*\.)/$1,/g;
> > return scalar reverse $text;
> > }
>
> Here's a direct Ruby translation:
>
> def commify( number )
> text = number.to_s.reverse
> text.gsub!(/(\d\d\d)(?=\d)(?!\d*\.)/, '\1,')
> text.reverse
> end

golf?

def commify(num)
num.to_s.reverse.scan(/..?.?/).join(",").reverse
end

... sorry, couldn't resist. Weak character.

cheers,
Mark


Christian Neukirchen

2/12/2005 11:06:00 AM

0

Mark Hubbart <discordantus@gmail.com> writes:

>> Here's a direct Ruby translation:
>>
>> def commify( number )
>> text = number.to_s.reverse
>> text.gsub!(/(\d\d\d)(?=\d)(?!\d*\.)/, '\1,')
>> text.reverse
>> end
>
> golf?
>
> def commify(num)
> num.to_s.reverse.scan(/..?.?/).join(",").reverse
> end
>
> ... sorry, couldn't resist. Weak character.

IMHO, that's even easier to read...

> cheers,
> Mark
>

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneuk...


Andrew Johnson

2/12/2005 4:56:00 PM

0

On Sat, 12 Feb 2005 09:32:49 +0900, Mark Hubbart <discordantus@gmail.com>
wrote:
[snip]

> golf?
>
> def commify(num)
> num.to_s.reverse.scan(/..?.?/).join(",").reverse
> end

That one doesn't do well with floats, which was what the poster
was dealing with.

As an aside, the commify routine from the Perl FAQ (shown earlier)
was actually designed as a means of commifying multiple numbers
in a string in a single pass:

str = "123456789.987654321 and $1500.00 and 3.14159"
p str.reverse.gsub(/(\d\d\d)(?=\d)(?!\d*\.)/,'\1,').reverse

So if, for example, you were pulling numbers from a data source
and creating an output string of a series of LaTeX tables, you
could build the entire string first with the raw numbers and
commify it all at once after the fact -- much more efficient than
commifying each number as you build the string. (this was, in
fact, the use-case that led to this particular solution).

regards,
andrew

--
Andrew L. Johnson http://www.s...
In theory, there's no difference between
theory and practice, but in practice there is!

William James

2/12/2005 9:16:00 PM

0


Andrew Johnson wrote:
> On Sat, 12 Feb 2005 09:32:49 +0900, Mark Hubbart
<discordantus@gmail.com>
> wrote:
> [snip]
>
> > golf?
> >
> > def commify(num)
> > num.to_s.reverse.scan(/..?.?/).join(",").reverse
> > end
>
> That one doesn't do well with floats, which was what the poster
> was dealing with.


I think this works properly:

* def commify( n )
* n.to_s.reverse.gsub(/(\d{3})(?=\d+-?$)/,'\1,').reverse
* end