首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将IDN域转换为Perl中的Punycode

将IDN域转换为Perl中的Punycode
EN

Code Review用户
提问于 2021-07-03 17:18:14
回答 1查看 278关注 0票数 5

描述

此脚本接受来自STDIN的任何域输入,并将unicode域转换为子代码。

特性

  • 任何抛出错误的域都会被忽略。
  • 当给任何ASCII域喂食时,它们都会通过。

转换P

代码语言:javascript
复制
#!/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输入:

代码语言:javascript
复制
дольщикиспб.рф
шляхтен.рф
สารสกัดจากสมุนไพร.com
google.com

Sample输出:

代码语言:javascript
复制
xn--90afmajeumr0f6a.xn--p1ai
xn--e1alhsoq4c.xn--p1ai
xn--12cau1c1a4atlh5dbe1gkg3hzj.com
google.com

我愿意接受任何反馈!

EN

回答 1

Code Review用户

回答已采纳

发布于 2021-07-11 20:15:26

这里有一些小注释:该程序使用的是谢邦

代码语言:javascript
复制
#!/usr/bin/perl -Wn

当脚本作为来自Shell的命令运行时,会使用shebang。在本例中,/usr/bin/perl用于运行命令。这就是所谓的系统perl,它附带了一个类似Unix的操作系统。但是,除了系统perl之外,用户还会安装其他perl可执行文件,例如使用perlbrew。在本例中,用户希望使用他当前选择的Perl解释器来运行您的脚本。它可能是系统perl,也可能是已安装的perl。通常,用户会安排设置PATH环境变量,以便Shell找到正确的perl。同样的事情可以通过更改成

代码语言:javascript
复制
#!/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

代码语言:javascript
复制
#! /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

代码语言:javascript
复制
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)");

}

您可以这样运行测试:

代码语言:javascript
复制
$ 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

或者像这样:

代码语言:javascript
复制
$ 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..2
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/263728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档