0

使用 bash:

$ echo '\u043f\u0441\u0438\u0445\u043e\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

4

2 回答 2

2

\u在 Perl 中并不意味着“Unicode 转义”。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中用于字符串转义的引号和类似引号的运算符

于 2018-12-19T12:08:51.713 回答
0

\uXXXX根本与 Punycode/IDN 无关。它看起来像是代表 Unicode 字符的 JSON 字符串格式,您需要为它们使用正确的工具。

首先,您必须在双引号内转义反斜杠,或使用单引号。

如果您不需要处理代理对,您可以简单地将数字转换为 unicode 字符。

#!/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";

如果您必须考虑它们,您仍然可以在没有非 CORE CPAN 模块的情况下进行转换。

#!/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:请高人指正我的英语不好,谢谢

于 2018-12-19T12:25:02.577 回答