Perl can use the thousands separator appropriate for your locale, as well as the appropriate decimal separator. The Number::Format from CPAN can do all sorts of interesting localizations, but POSIX can do it.
I debated offering an example in Learning Perl (7th Edition), but POSIX‘s localeconv function returns a hash reference. And, although I’ve added an appendix covering experimental features, I didn’t want to go through enough Perl to explain slices and postfix dereferencing.
Before I get to the Perl, there are a few tips. The locale command with no arguments shows you what you have set so far:
$ locale LANG="en_US.UTF-8" LC_COLLATE="de_DE.UTF-8" LC_CTYPE="de_DE.UTF-8" LC_MESSAGES="de_DE.UTF-8" LC_MONETARY="de_DE.UTF-8" LC_NUMERIC="de_DE.UTF-8" LC_TIME="de_DE.UTF-8" LC_ALL="de_DE.UTF-8"
The locale command with -a shows you what you have installed on your system. The locale is really groups of files (maybe in /usr/share/locale) that have settings for various things, such as the monetary thousands and decimal separators.
I can get these settings POSIX‘s localeconv, which returns a hash reference. Note that if you haven’t completely set your locale, some of the keys may be missing.
use v5.22;
use feature qw(postderef);
no warnings qw(experimental);
use POSIX qw(locale_h);
# returns a hash reference, which we don't cover in Learning Perl
# LC_NUMERIC should be set. For instance:
# % export LC_ALL=de_DE.UTF-8
my $hash = localeconv();
# Reading about locales can help
# http://lh.2xlibre.net/locales/
my( $thousands, $decimal ) =
$hash->@{qw(mon_thousands_sep mon_decimal_point)};
# set some defaults if the locale did not set them
$thousands //= ',';
$decimal //= '.';
# treat the number as a string
my $number = join $decimal, 123456789, 1234;
1 while ($number =~ s/^(-?\d+)(\d\d\d)/$1$thousands$2/);
say "Number is $number";
When I run this under different locales, the output is a bit different:
$ LC_ALL=en_US.UTF-8 perl5.22.0 test.pl Number is 123,456,789.1234 $ LC_ALL=de_DE.UTF-8 perl5.22.0 test.pl Number is 123.456.789,1234
Be careful – not all locals separate every three digits. For instance, India (at least English language locales there). There, 1,000,000 is apparently written 10,00,000 .
Fortunately, CPAN can help. 🙂 See CLDR::Number
#!/usr/bin/env perluse v5.10;
use CLDR::Number;
my $cldr = CLDR::Number->new(locale => 'en-in');
my $decf = $cldr->decimal_formatter;
say $decf->format(1_000_000);
perl:~$ perl test.pl
10,00,000