Мне нужно обрабатывать кодировку и декодирование URI (т.е. процент) в моем Perl script. Как это сделать?
Это вопрос официального официального perlfaq. Мы импортируем perlfaq в Stack Overflow.
Мне нужно обрабатывать кодировку и декодирование URI (т.е. процент) в моем Perl script. Как это сделать?
Это вопрос официального официального perlfaq. Мы импортируем perlfaq в Stack Overflow.
Это официальный ответ за минусом последующих изменений.
Те %
encodings обрабатывают зарезервированные символы в URI, как описано в RFC 2396, раздел 2. Эта кодировка заменяет зарезервированный символ шестнадцатеричным представлением номера символа из таблицы US-ASCII. Например, двоеточие, :
, становится %3A
.
В сценариях CGI вам не нужно беспокоиться об декодировании URI, если вы используете CGI.pm. Вам не нужно будет обрабатывать URI самостоятельно, либо по пути, либо по пути.
Если вам нужно самостоятельно закодировать строку, помните, что вы никогда не должны пытаться кодировать уже сконфигурированный URI. Вам нужно убрать компоненты отдельно, а затем собрать их вместе. Чтобы закодировать строку, вы можете использовать модуль URI::Escape. Функция uri_escape
возвращает 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;
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;
Кодеры помогают кодировщикам - обмен знаниями!
Возможно, это поможет решить, какой метод выбрать.
Контрольные показатели по 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% --