17

我需要在我的 Perl 脚本中处理 URI(即百分比)编码和解码。我怎么做?


这是来自官方 perlfaq的一个问题。我们将perlfaq 导入 Stack Overflow

4

3 回答 3

27

这是官方常见问题解答减去后续编辑。

这些%编码处理 URI 中的保留字符,如RFC 2396 第 2 节中所述。此编码将保留字符替换为 US-ASCII 表中字符编号的十六进制表示。例如,冒号:, 变为%3A

在 CGI 脚本中,如果您使用CGI.pm,则不必担心解码 URI 。您不必自己处理 URI,无论是在输入还是输出的过程中。

如果您必须自己对字符串进行编码,请记住,您永远不应该尝试对已经组成的 URI 进行编码。您需要单独转义组件,然后将它们放在一起。要对字符串进行编码,您可以使用URI::Escape模块。该uri_escape函数返回转义字符串:

my $original = "Colon : Hash # Percent %";

my $escaped = uri_escape( $original );

print "$escaped\n"; # 'Colon%20%3A%20Hash%20%23%20Percent%20%25'

要解码字符串,请使用 uri_unescape 函数:

my $unescaped = uri_unescape( $escaped );

print $unescaped; # back to original

如果你想自己做,你只需要用它们的编码替换保留的字符。全局替换是一种方法:

# encode
$string =~ s/([^^A-Za-z0-9\-_.!~*'()])/ sprintf "%%%0x", ord $1 /eg;

#decode
$string =~ s/%([A-Fa-f\d]{2})/chr hex $1/eg;
于 2010-12-22T15:13:16.793 回答
4

DIY编码(改进以上版本):

$string =~ s/([^^A-Za-z0-9\-_.!~*'()])/ sprintf "%%%02x", ord $1 /eg;

(注意 '%02x' 而不仅仅是 '%0x')

DIY解码(添加'+' -> ''):

$string =~ s/\+/ /g; $string =~ s/%([A-Fa-f\d]{2})/chr hex $1/eg;

编码员帮助编码员 - 以物易物!

于 2015-11-12T17:21:12.263 回答
1

也许这将有助于决定选择哪种方法。

perl 5.22.1 的基准测试。对于给定的每个函数都返回相同的结果$string

代码:

#!/usr/bin/env perl

my $string = "ala ma 0,5 litra 40%'owej vodki :)";

use Net::Curl::Easy;
my $easy = Net::Curl::Easy->new();
use URI::Encode qw( uri_encode );
use URI::Escape qw( uri_escape );
use Benchmark(cmpthese);

cmpthese(10_000, {
    'a' => sub {
        $string =~ s/([^^A-Za-z0-9\-_.!~*'()])/ sprintf "%%%0x", ord $1 /eg;
    },
    'b' => sub {
        $easy->escape( $string );
    },
    'c' => sub {
        uri_encode( $string, {encode_reserved => 1} ); 
    },
    'd' => sub {
        uri_escape( $string );
    },
});

和结果:

    Rate    c    d    a    b
c  457/s   -- -33% -65% -89%
d  680/s  49%   -- -48% -84%
a 1307/s 186%  92%   -- -69%
b 4237/s 826% 523% 224%   --
于 2016-04-30T15:27:49.813 回答