Как использовать Perl, как мне декодировать или создавать эти% -encodings в Интернете?

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


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

Ответ 1

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

Те % 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;

Ответ 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%   --