我需要在Perl脚本中处理URI(即百分比)编码和解码。我该怎么做?
这是来自official perlfaq的问题。我们是importing the perlfaq to Stack Overflow。
答案 0 :(得分:19)
这是official FAQ answer减去后续修改。
这些%
编码处理URI中的保留字符,如RFC 2396, Section 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;
答案 1 :(得分:2)
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;
编码员帮助编码员 - 交换知识!
答案 2 :(得分: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% --