Используя Perl, как мне декодировать или создавать эти% -кодировки в Интернете? - PullRequest
11 голосов
/ 22 декабря 2010

Мне нужно обрабатывать кодирование и декодирование URI (т.е. процентов) в моем скрипте Perl. Как мне это сделать?


Это вопрос от официального perlfaq . Мы импортируем perlfaq в Stack Overflow .

Ответы [ 3 ]

19 голосов
/ 22 декабря 2010

Это официальный ответ на часто задаваемые вопросы минус последующие правки.

Эти % кодировки обрабатывают зарезервированные символы в URI, как описано в RFC 2396, раздел 2 . Эта кодировка заменяет зарезервированный символ шестнадцатеричным представлением номера символа из таблицы US-ASCII. Например, двоеточие : становится %3A.

В CGI-скриптах вам не нужно беспокоиться о декодировании URI, если вы используете CGI.pm . Вы не должны обрабатывать 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 голосов
/ 12 ноября 2015

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;

Кодеры помогают кодерам - обмениваются знаниями!

1 голос
/ 30 апреля 2016

Может быть, это поможет решить, какой метод выбрать.

Тесты на 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%   --
...