【问题标题】:Using Perl, how do I decode or create those %-encodings on the web?使用 Perl,我如何在网络上解码或创建那些 %-encodings?
【发布时间】:2011-05-29 11:23:33
【问题描述】:

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


这是来自official perlfaq 的问题。我们是importing the perlfaq to Stack Overflow

【问题讨论】:

    标签: perl url-encoding percent-encoding


    【解决方案1】:

    这是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;
    

    【讨论】:

    【解决方案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;
    

    程序员帮助程序员 - 以物易物!

    【讨论】:

      【解决方案3】:

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

      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%   --
      

      【讨论】:

      • 该测试存在一个主要问题:每次迭代都会修改全局 $string,从而为下一次迭代带来更多工作。所以'a'和'b'的工作量比'c'和'd'少。在 cmpthese() 完成后尝试打印 length($string)。
      猜你喜欢
      • 1970-01-01
      • 2012-01-16
      • 2013-02-28
      • 1970-01-01
      • 1970-01-01
      • 2020-12-25
      • 2015-09-09
      • 2021-04-17
      • 2017-11-28
      相关资源
      最近更新 更多