描述
此脚本接受来自STDIN的任何域输入,并将unicode域转换为子代码。
特性
转换P
#!/usr/bin/perl -Wn
use strict;
use Try::Tiny;
use Net::IDN::Encode ':all';
use open ':std', ':encoding(UTF-8)';
try {
chomp $_;
printf "%s\n",domain_to_ascii $_;
}Sample输入:
дольщикиспб.рф
шляхтен.рф
สารสกัดจากสมุนไพร.com
google.comSample输出:
xn--90afmajeumr0f6a.xn--p1ai
xn--e1alhsoq4c.xn--p1ai
xn--12cau1c1a4atlh5dbe1gkg3hzj.com
google.com我愿意接受任何反馈!
发布于 2021-07-11 20:15:26
这里有一些小注释:该程序使用的是谢邦
#!/usr/bin/perl -Wn当脚本作为来自Shell的命令运行时,会使用shebang。在本例中,/usr/bin/perl用于运行命令。这就是所谓的系统perl,它附带了一个类似Unix的操作系统。但是,除了系统perl之外,用户还会安装其他perl可执行文件,例如使用perlbrew。在本例中,用户希望使用他当前选择的Perl解释器来运行您的脚本。它可能是系统perl,也可能是已安装的perl。通常,用户会安排设置PATH环境变量,以便Shell找到正确的perl。同样的事情可以通过更改成
#!/usr/bin/env perl现在,脚本更易于移植,因为它可以适应当前用户的设置。然而,有一个复杂的问题:当使用perl时,不可能在shebang行中将参数传递给/usr/bin/env。在您的示例中,您尝试将选项-Wn传递给perl,但不能以可移植的方式执行,请参见为什么在这种情况下我能够将参数传递给/usr/bin/env?。
幸运的是,很少有必要在shebang行中将参数传递给perl。在Perl脚本本身中更好地启用了-W和-n。与其将-W传递给perl,您还可以在D21脚本中使用warnings实用化。类似地,-n选项用于在脚本周围设置一个逐行读取的STDIN循环,这可以很容易地在脚本本身中实现。
另一件可以帮助记录您的程序(从而使维护变得更容易)的事情是包括一些描述程序预期行为的单元测试。例如:
p.pl:
#! /usr/bin/env perl
use feature qw(say);
use open ':std', ':encoding(UTF-8)';
use warnings;
use strict;
use Try::Tiny;
use Net::IDN::Encode 'domain_to_ascii';
# Written as a modulino: See Chapter 17 in "Mastering Perl". Executes main() if
# run as script, otherwise, if the file is imported from the test scripts,
# main() is not run.
main() unless caller;
sub main {
while (<>) {
my $line = parse_line($_);
last if !defined $line;
say $line;
}
}
sub parse_line {
my ($line) = @_;
chomp $line;
my $result = try {
domain_to_ascii( $line );
};
return $result;
}t/main.t:
use strict;
use warnings;
use utf8;
use open ':std', ':encoding(utf-8)';
use Test2::V0;
use lib '.';
require "p.pl";
{
subtest "basic" => \&basic;
subtest "fails" => \&fails;
# TODO: Complete the test suite..
done_testing;
}
sub basic {
my @data = (['дольщикиспб.рф', 'xn--90afmajeumr0f6a.xn--p1ai'],
['สารสกัดจากสมุนไพร.com', 'xn--12cau1c1a4atlh5dbe1gkg3hzj.com'],
['шляхтен.рф', 'xn--e1alhsoq4c.xn--p1ai'],
['google.com', 'google.com']
);
my $i = 1;
for my $item (@data) {
my ($input, $output) = @$item;
is(parse_line($input), $output, "basic $i");
$i++;
}
}
sub fails {
is(parse_line("...."), U(), "empty label");
is(parse_line("1234567890123456789012345678901234567890123456789012345678901234"), U(), "label too long (max 63 characters)");
}您可以这样运行测试:
$ prove t
t/main.t .. ok
All tests successful.
Files=1, Tests=2, 0 wallclock secs ( 0.01 usr 0.00 sys + 0.07 cusr 0.01 csys = 0.09 CPU)
Result: PASS或者像这样:
$ perl t/main.t
# Seeded srand with seed '20210711' from local date.
ok 1 - basic {
ok 1 - basic 1
ok 2 - basic 2
ok 3 - basic 3
ok 4 - basic 4
1..4
}
ok 2 - fails {
ok 1 - empty label
ok 2 - label too long (max 63 characters)
1..2
}
1..2https://codereview.stackexchange.com/questions/263728
复制相似问题