Perl: Конвертация домена в зоне .рф в punycode
Ну вот, добрался прогресс и до нас. Сегодня пришло тех.задание проапдейтить мой SEO-инструмент, что б можно было использовать домены в зоне .рф. Казалось бы что тут сложного, а не тут-то было, из четырех опробованных готовых библиотек, найденных на CPAN, только одна корректно отработала.
URI::UTF8::Punycode - Punycode conversion of UTF-8 string.
Вот моё готовое решение по её использованию:
перевод в ASCII:
перевод в UTF8:
Где еще почитать:
Wikipedia: Punycode
Perl перекодировка в Punycode
Функции PHP для работы с IDN-доменами
PHP PEAR-модуль для работы с IDN
URI::UTF8::Punycode - Punycode conversion of UTF-8 string.
Вот моё готовое решение по её использованию:
перевод в ASCII:
use URI::UTF8::Punycode; my $domain = 'президент.рф'; print puny_encode_domain($domain); sub puny_encode_domain { my $domain = shift; my @puny_words = (); foreach my $d (split(/\./, $domain)) { if ($d !~ m/[a-zA-Z0-9]/i) { $d = URI::UTF8::Punycode::puny_enc($d); } push(@puny_words, $d); } my $result = join('.', @puny_words); return $result; }
перевод в UTF8:
use URI::UTF8::Punycode; my $domain = 'xn--d1abbgf6aiiy.xn--p1ai'; print puny_decode_domain($domain); sub puny_decode_domain { my $domain = shift; my @puny_words = (); foreach my $d (split(/\./, $domain)) { if ($d =~ /^xn--/) { $d = URI::UTF8::Punycode::puny_dec($d); } push(@puny_words, $d); } my $result = join('.', @puny_words); return $result; }
Где еще почитать:
Wikipedia: Punycode
Perl перекодировка в Punycode
Функции PHP для работы с IDN-доменами
PHP PEAR-модуль для работы с IDN
Похожие материалы:
Комментарии:
4 Февраля 2013 (05:16:22)
Rus
(гость)
• ответить
Ога, вот так правильно. цифры нельзя исключать. ну и с /i не надо печислять A-Z отдельно
if ($d !~ m/[a-z]/i)
if ($d !~ m/[a-z]/i)
8 Сентября 2014 (09:40:09)
Snelius
(гость)
• ответить
можно использовать core модуль URI для конвертации, причём он ничего не сделает с латинскими именами. например так print URI->new('http://домен.рф')->host.
12 Марта 2015 (16:22:14)
Магомед
(гость)
• ответить
Добрый день.. ребята.. помощь нужна.. я пытался по этим готовым решениям свою задачу решить но не получается..
Сервер centos 6.6 с dns сервером bind. и возникла такая необходимость чтоб автоматом перекодировала домены рф.
есть файл (test) с содержанием списка доменов .рф все домены каждая в отдельности в новой строке..
мне нужен скрипт который ее прочтет переведет все строки на punycode и запишет в другой файл (test1)
заранее спасибо
Сервер centos 6.6 с dns сервером bind. и возникла такая необходимость чтоб автоматом перекодировала домены рф.
есть файл (test) с содержанием списка доменов .рф все домены каждая в отдельности в новой строке..
мне нужен скрипт который ее прочтет переведет все строки на punycode и запишет в другой файл (test1)
заранее спасибо
13 Марта 2015 (13:15:34)
Магомед
(гость)
• ответить
пытаюсь сделать по первому скрипту.. для просмотра как скрипт работает я ничего не менял. создал файл 1.pl дал права 777 и запускаю. я не такой знаток скритов. может что я не так делаю
вот вывод
./1.pl
./1.pl: line 1: sub: команда не найдена
./1.pl: line 2: my: команда не найдена
./1.pl: line 4: syntax error near unexpected token `('
./1.pl: line 4: ` my @puny_words = ();'
вот вывод
./1.pl
./1.pl: line 1: sub: команда не найдена
./1.pl: line 2: my: команда не найдена
./1.pl: line 4: syntax error near unexpected token `('
./1.pl: line 4: ` my @puny_words = ();'
13 Марта 2015 (13:16:28)
Магомед
(гость)
• ответить
sub puny_encode_domain {
my $domain = shift;
my @puny_words = ();
foreach my $d (split(/\./, $domain)) {
if ($d !~ m/[a-zA-Z0-9]/i) {
$d = URI::UTF8:unycode:uny_enc($d);
}
push(@puny_words, $d);
}
my $result = join('.', @puny_words);
return $result;
}
my $domain = shift;
my @puny_words = ();
foreach my $d (split(/\./, $domain)) {
if ($d !~ m/[a-zA-Z0-9]/i) {
$d = URI::UTF8:unycode:uny_enc($d);
}
push(@puny_words, $d);
}
my $result = join('.', @puny_words);
return $result;
}
19 Апреля 2016 (23:40:33)
Elias292
(гость)
• ответить
Я вот так поменял:
sub puny_encode_domain {
$domain = shift;
@puny_words = ();
foreach $d (split(/\./, $domain)) {
if ($d !~ m/[a-zA-Z]/i) {
$d = URI::UTF8:unycode:uny_enc($d) unless $d =~ m/^\d+$/;
}
push(@puny_words, $d);
}
$result = join('.', @puny_words);
return $result;
}
вроде работает.
sub puny_encode_domain {
$domain = shift;
@puny_words = ();
foreach $d (split(/\./, $domain)) {
if ($d !~ m/[a-zA-Z]/i) {
$d = URI::UTF8:unycode:uny_enc($d) unless $d =~ m/^\d+$/;
}
push(@puny_words, $d);
}
$result = join('.', @puny_words);
return $result;
}
вроде работает.
Условие
if ($d !~ m/[a-zA-Z0-9]/i) {
не точное...
Например из за него "а1" не конвертируется в xn--1-7sb