Robert
Robert

Reputation: 8618

Get the language code from the native language name in Perl

When looking for a language's ISO369 code, this works fine with the English name of the language:

perl -MLocale::Language -e 'print language2code("German"), "\n";'
de

But it does not work with the native language name:

perl -MLocale::Language -e 'print language2code("Deutsch"), "\n";'

Background: I have text in a few languages and need to generate a HTML hreflang link. The text is always labeled with its native language name (e.g., "English", "Español", or "Deutsch"). I don't want to switch the (system) language before the lookup because I don't know to which language to switch. Right now I have my own lookup table that maps e.g., "English" => "en" and "Deutsch" => "de", but I was wondering if there was an easier way that does not need me to maintain that table.

How can I get from a language's native name to its ISO code?

Upvotes: 2

Views: 246

Answers (2)

Robert
Robert

Reputation: 8618

Here's what I ended up with, just for completeness, based on @bytepusher's answer. All credit to @bytepusher.

use strict;
use warnings;
use Locales;  # install with cpan install Locales, not just cpan install Locales::Language
# Or, with UTF8:
# use utf8;
# use Locales unicode => 1;

sub code_for {
    my ($lang) = @_;

    foreach my $lcode (Locales::->new()->get_language_codes()) {
        my $loc = Locales->new($lcode);
        next unless($loc);
        my $code = $loc->get_code_from_language($lang);
        return $code if ($code);
    }
    return undef;
}


foreach my $lang (qw(Deutsch Español English)) {
    print "$lang: ", code_for($lang), "\n";
}

Output

Deutsch: de

Español: es

English: en

Upvotes: 0

bytepusher
bytepusher

Reputation: 1578

according to the docs, Locales::Language on cpan should enable you to do just that. Have you tried it?

Edit:

I installed Locales via cpan, which worked fine for me. cpan Locales

Then:

use Locales;
my $locale = Locale->new('de_DE');

warn $locale->get_code_from_language("Deutsch"); # de
warn $locale->get_code_from_language("Englisch"); # en

Edit again:

After clarification, I now know what OP wants. I think the easiest way to achieve this is to build a more complete lookup using the Locales module I mentioned. On my rather old machine, that does not take long at all:

my %locale_lookup
for my $code ( $locale->get_language_codes ){

    my $locale = Locales->new($code) // next; # ignore codes w/o locale
    $locale_lookup{$locale->get_language_from_code} = $locale;

}

...
my $locale = $locale_lookup{$tag}; # e.g. "Deutsch" 
my $code = $locale->get_code_from_language($tag);
...

Upvotes: 2

Related Questions