Punycode ... с помощью Perl - PullRequest
       108

Punycode ... с помощью Perl

0 голосов
/ 19 декабря 2018

С bash:

$ echo 'u043f \ u0438 \ u045e \ u0442 \ u0435 \ u0440 \ u0430 \ u043f \ u0438 \ u044f.net' |ascii2uni -a U -q

психотерапия.net

Как это сделать с помощью perl?

use utf8;
use URI::_punycode (decode_punycode,encode_punycode);

$fqdn = "\u043f\u0441\u0438\u0445\u043e\u0442\u0435\u0440\u0430\u043f\u0438\u044f.net";

$fqdn = `echo $fqdn | ascii2uni -a U -q`;
$unicode  = encode_punycode($fqdn);
print "$unicode\n";

возвращает:

$ perl test.pl

043f044104380445043e0442043504400430043f0438044f.net

Ответы [ 2 ]

0 голосов
/ 19 декабря 2018

\uXXXX не имеет отношения к Punycode / IDN вообще.Похоже, что строковый формат JSON представляет символы Юникода, и вам нужно использовать правильные инструменты для них.

Во-первых, вы должны избегать обратной косой черты внутри двойных кавычек или использовать одинарные кавычки.

Есливам не нужно иметь дело с суррогатными парами, вы можете просто конвертировать числа в символы юникода.

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Encode;

my $fqdn = '\u043f\u0441\u0438\u0445\u043e\u0442\u0435\u0440\u0430\u043f\u0438\u044f.net';
$fqdn =~ s/\\u([[:xdigit:]]{4})/chr(hex($1))/ge;

print encode_utf8 $fqdn;
print "\n";

Если вам нужно учесть их, вы все равно можете конвертировать без CPAN-модулей без CORE.

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Encode;

my $fqdn = '\u043f\u0441\u0438\u0445\u043e\u0442\u0435\u0440\u0430\u043f\u0438\u044f.net';

my $re_hex = qr/[[:xdigit:]]{4}/;
my $re_uni = qr/\\u$re_hex/;
my $re_uni_capture = qr/\\u($re_hex)/;

$fqdn = join q{}, map {
    /^$re_uni/
        ? decode 'utf-16-be', pack "n*", map { hex } m/$re_uni_capture/g
        : $_
} split qr/(${re_uni}*)/, $fqdn;

print encode_utf8 $fqdn;
print "\n";

PS: Пожалуйста, кто-нибудь исправит мой плохой английский, спасибо

0 голосов
/ 19 декабря 2018

\u в Perl не означает «Unicode escape».Perl использует синтаксис \N{U+43f}.Изменяя вашу программу в соответствии с синтаксисом Perl, она работает для меня:

#!perl
use strict;
use warnings;
use utf8;
use URI::_punycode qw(decode_punycode encode_punycode);

binmode STDOUT, ':encoding(UTF-8)';

my $fqdn = "\N{U+043f}\N{U+0441}\N{U+0438}\N{U+0445}\N{U+043e}\N{U+0442}\N{U+0435}\N{U+0440}\N{U+0430}\N{U+043f}\N{U+0438}\N{U+044f}.net";
print "FQDN: [$fqdn]\n";

print "\n---\n";
my $punicode  = encode_punycode($fqdn);
print "\n---\n";
print "[$punicode]\n";

Для меня это выводит следующее, что, я полагаю, является ожидаемым результатом:

FQDN: [психотерапия.net]

---

---
[.net-43d3auc5ciekjq7byl]

Если выЕсли fqdn буквально в виде строки, например \uabcd\u1234..., вы можете преобразовать ее в Unicode, используя:

$fqdn =~ s/\\u([[:xdigit:]]{4})/chr(hex($1))/ge;

Для получения дополнительной информации см. другой ответ.

См. также

Операторы кавычек и кавычек в Perl для строк экранированных символов

...