Currency formatting with regexp

J

Jim Van Fleet

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
 
M

Mark Hubbart

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
 
A

Andrew Johnson

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

William James

Andrew said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top