package Lingua::NL::Numbers; $VERSION = '1.3'; use strict; my $numbers = { 0 => 'nul', 1 => 'een', 2 => 'twee', 3 => 'drie', 4 => 'vier', 5 => 'vijf', 6 => 'zes', 7 => 'zeven', 8 => 'acht', 9 => 'negen', 10 => 'tien', 11 => 'elf', 12 => 'twaalf', 13 => 'dertien', 14 => 'veertien', 15 => 'vijftien', 16 => 'zestien', 17 => 'zeventien', 18 => 'achtien', 19 => 'negentien', 20 => 'twintig', 30 => 'dertig', 40 => 'veertig', 50 => 'vijftig', 60 => 'zestig', 70 => 'zeventig', 80 => 'tachtig', 90 => 'negentig', }; sub new { my $class = shift; my $number = shift || ''; my $self = {}; bless $self, $class; if( $number =~ /\d+/ ) { return( $self->parse($number) ); }; return( $self ); }; sub parse { my $self = shift; my $number = shift; my $digits; my $ret = ''; if( defined($numbers->{$number}) ) { $ret = $numbers->{$number}; } else { my $ret_array = []; @{$digits} = reverse( split('', $number) ); # tens of billions if( defined($digits->[10]) && ($digits->[10] != 0) ) { my $temp = $self->_formatTens( $digits->[9], $digits->[10] ); unshift @{$ret_array}, "$temp biljoen"; } elsif( defined($digits->[9]) && ($digits->[9] != 0) ) { unshift @{$ret_array}, $self->_formatLarge( $digits->[9], ' biljoen' ); }; # hundreds of millions if( defined($digits->[8]) && ($digits->[8] != 0) ) { if( ($digits->[7] == 0) && ($digits->[6] == 0) ) { unshift @{$ret_array}, $self->_formatLarge( $digits->[8], ' honderd miljard' ); } else { unshift @{$ret_array}, $self->_formatLarge( $digits->[8], ' honderd' ); }; }; # tens of millions if( defined($digits->[7]) && ($digits->[7] != 0) ) { my $temp = $self->_formatTens( $digits->[6], $digits->[7] ); unshift @{$ret_array}, "$temp miljard"; } elsif( defined($digits->[6]) && ($digits->[6] != 0) ) { unshift @{$ret_array}, $self->_formatLarge( $digits->[6], ' miljard' ); }; # hundreds of thousands if( defined($digits->[5]) && ($digits->[5] != 0) ) { if( ($digits->[4] == 0) && ($digits->[3] == 0) ) { unshift @{$ret_array}, $self->_formatLarge( $digits->[5], ' honderd duizend' ); } else { unshift @{$ret_array}, $self->_formatLarge( $digits->[5], ' honderd' ); }; }; # tens of thousands if( defined($digits->[4]) && ($digits->[4] != 0) ) { my $temp = $self->_formatTens( $digits->[3], $digits->[4] ); unshift @{$ret_array}, "$temp duizend"; } elsif( defined($digits->[3]) && ($digits->[3] == 1) ) { unshift @{$ret_array}, ' duizend'; } elsif( defined($digits->[3]) && ($digits->[3] != 0) ) { unshift @{$ret_array}, $self->_formatLarge( $digits->[3], ' duizend' ); }; # hundreds if( defined($digits->[2]) && ($digits->[2] == 1) ) { unshift @{$ret_array}, 'honderd'; } elsif( defined($digits->[2]) && ($digits->[2] != 0) ) { unshift @{$ret_array}, $self->_formatLarge( $digits->[2], 'honderd' ); }; # tens unshift @{$ret_array}, $self->_formatTens( $digits->[0], $digits->[1], 'en' ); $ret = $self->_sortReturn( $ret_array, $digits ); }; return( $ret ); }; sub _sortReturn { my $self = shift; my $ret_array = shift; my $digits = shift; my $large_nums = 0; my $ret = ''; my $size = @{$ret_array}; if( $size == 1 ) { return( $ret_array->[0] ); } elsif( $size > 1 ) { $large_nums = 1; }; for( my $i = $size; $i > 0; $i-- ) { if( defined($ret_array->[$i]) ) { if( $ret_array->[$i] =~ /(miljard|duizend)/ ) { $ret .= $ret_array->[$i] .', '; } else { $ret .= $ret_array->[$i] .' '; }; }; }; if( ($digits->[0] == 0) && ($digits->[1] == 0) ) { # do nothing } elsif( ($digits->[0] == 0) || ($digits->[1] == 0) || ($digits->[1] == 1) ) { if( $large_nums ) { $ret .= ' en '; }; $ret .= $ret_array->[0]; } else { $ret .= ' '. $ret_array->[0]; }; $ret =~ s/(^ |\s{2,}| $)/ /g; return( $ret ); }; sub _formatTens { my $self = shift; my $units = shift; my $tens = shift; my $en = shift || ' en '; # Both digits are zero unless( $units || $tens ) { return; }; if( $tens == 0 ) { return( $numbers->{$units} ); } elsif( ($tens == 1) || ($units == 0) ) { my $temp = $tens . $units; return( $numbers->{$temp} ); }; my $temp = $tens . 0; return( $numbers->{$units} . $en . $numbers->{$temp} ); }; sub _formatLarge { my $self = shift; my $digit = shift; my $word = shift; my $ret = "$numbers->{$digit}$word"; return( $ret ); }; 1; =pod =head1 NAME Lingua::NL::Numbers - Perl module for converting numeric values into their Dutch equivalents =head1 DESCRIPTION Initial release, documentation and updates will follow. =head1 SYNOPSIS use Lingua::NL::Numbers; my $numbers = Lingua::NL::Numbers->new; my $text = $numbers->parse( 123 ); # prints 'een honderd, drie en twintig' print $text; =head1 KNOWN BUGS None, but that does not mean there are not any. =head1 AUTHOR Alistair Francis, http://search.cpan.org/~friffin/ =cut