A lookaround method that will work on any numbers embedded in a string (but will not commify after a decimal point):
sub commify {
local $_ = shift;
s{(?<!\d|\.)(\d{4,})}
{my $n = $1;
$n=~s/(?<=.)(?=(?:.{3})+$)/,/g;
$n;
}eg;
return $_;
}
If you prefer the FAQ rule of only working on things that begin with digits or -,
sub commify {
local $_ = shift;
s{(?:(?<=^)|(?<=^-))(\d{4,})}
{my $n = $1;
$n=~s/(?<=.)(?=(?:.{3})+$)/,/g;
$n;
}e;
return $_;
}
This one does a single pattern match and then uses substr() to insert the commas:
sub commify {
local $_ = shift;
if (/^-?(\d{4,})/g) {
for (my $p=$+[1]; $p>$-[1]; $p-=3) {
substr($_,$p,0) = ','
}
}
return $_;
}
|