Lingua-ENG-Inflect
view release on metacpan or search on metacpan
lib/Lingua/ENG/Inflect.pm view on Meta::CPAN
return $ind<@mill ? $mill[$ind] : ' ???illion'; }
sub unit { return $unit[$_[0]]. mill($_[1]); }
sub ten
{
return $ten[$_[0]] . ($_[0]&&$_[1]?'-':'') . $unit[$_[1]] . mill($_[2])
if $_[0] ne '1';
return $teen[$_[1]]. $mill[$_[2]||0];
}
sub hund
{
return unit($_[0]) . " hundred" . ($_[1] || $_[2] ? " $_[4] " : '')
. ten($_[1],$_[2]) . mill($_[3]) . ', ' if $_[0];
return ten($_[1],$_[2]) . mill($_[3]) . ', ' if $_[1] || $_[2];
return '';
}
sub enword
{
my ($num,$group,$zero,$one,$comma,$and) = @_;
if ($group==1)
{
$num =~ s/(\d)/ ($1==1 ? " $one" : $1 ? unit($1) :" $zero")."$comma " /eg;
}
elsif ($group==2)
{
$num =~ s/(\d)(\d)/ ($1 ? ten($1,$2) : $2 ? " $zero " . unit($2) : " $zero $zero") . "$comma " /eg;
$num =~ s/(\d)/ ($1 ? unit($1) :" $zero")."$comma " /e;
}
elsif ($group==3)
{
$num =~ s/(\d)(\d)(\d)/ ($1==1 ? " $one" : $1 ? unit($1) :" $zero")." ".($2 ? ten($2,$3) : $3 ? " $zero " . unit($3) : " $zero $zero") . "$comma " /eg;
$num =~ s/(\d)(\d)/ ($1 ? ten($1,$2) : $2 ? " $zero " . unit($2) : " $zero $zero") . "$comma " /e;
$num =~ s/(\d)/ ($1==1 ? " $one" : $1 ? unit($1) :" $zero")."$comma " /e;
}
elsif ($num+0==0) {
$num = $zero;
}
elsif ($num+0==1) {
$num = $one;
}
else {
$num =~ s/\A\s*0+//;
my $mill = 0;
1 while $num =~ s/(\d)(\d)(\d)(?=\D*\Z)/ hund($1,$2,$3,$mill++,$and) /e;
$num =~ s/(\d)(\d)(?=\D*\Z)/ ten($1,$2,$mill)."$comma " /e;
$num =~ s/(\d)(?=\D*\Z)/ unit($1,$mill) . "$comma "/e;
}
return $num;
}
sub NUMWORDS
{
my $num = shift;
if (@_ % 2 and require Carp) {
die "Missing value in option list (odd number of option args) at"
. join ' line ', (caller)[1,2];
}
my %arg = ( %default_args, @_ );
my $group = $arg{group};
# Handle "stylistic" conversions (up to a given threshold)...
if (exists $arg{threshold} && $num > $arg{threshold}) {
my ($whole, $frac) = split /[.]/, $num;
while ($arg{comma}) {
$whole =~ s{ (\d) ( \d{3}(?:,|\z) ) }{$1,$2}xms
or last;
}
return $frac ? "$whole.$frac" : $whole;
}
die "Bad chunking option: $group\n" unless $group =~ /\A[0-3]\Z/;
my $sign = ($num =~ /\A\s*\+/) ? "plus"
: ($num =~ /\A\s*\-/) ? "minus"
: '';
my ($zero, $one) = @arg{'zero','one'};
my $comma = $arg{comma};
my $and = $arg{'and'};
my $ord = $num =~ s/(st|nd|rd|th)\Z//;
my @chunks = ($arg{decimal})
? $group ? split(/\./, $num) : split(/\./, $num, 2)
: ($num);
my $first = 1;
if ($chunks[0] eq '') { $first=0; shift @chunks; }
foreach ( @chunks )
{
s/\D//g;
$_ = '0' unless $_;
if (!$group && !$first) { $_ = enword($_,1,$zero,$one,$comma,$and) }
else { $_ = enword($_,$group,$zero,$one,$comma,$and) }
s/, \Z//;
s/\s+,/,/g;
s/, (\S+)\s+\Z/ $and $1/ if !$group and $first;
s/\s+/ /g;
s/(\A\s|\s\Z)//g;
$first = '' if $first;
}
my @numchunks = ();
if ($first =~ /0/)
{
unshift @chunks, '';
}
else
{
@numchunks = split /\Q$comma /, $chunks[0];
}
$numchunks[-1] =~ s/($ordinal_suff)\Z/$ordinal{$1}/
( run in 2.852 seconds using v1.01-cache-2.11-cpan-364913b4093 )