2010-12-22 19 views

Antwort

18

Dies ist die official FAQ answer minus nachfolgende Bearbeitungen. Diese % Codierungen behandeln reservierte Zeichen in URIs, wie in RFC 2396, Section 2 beschrieben. Diese Codierung ersetzt das reservierte Zeichen durch die hexadezimale Darstellung der Zeichennummer aus der US-ASCII-Tabelle. Zum Beispiel wird ein Doppelpunkt, :, %3A.

In CGI-Skripten müssen Sie sich keine Gedanken über die Dekodierung von URIs machen, wenn Sie CGI.pm verwenden. Sie sollten den URI weder auf dem Hinweg noch auf dem Weg selbst bearbeiten müssen.

Wenn Sie eine Zeichenfolge selbst codieren müssen, denken Sie daran, dass Sie niemals versuchen sollten, eine bereits erstellte URI zu codieren. Sie müssen die Komponenten getrennt entkommen und dann zusammenfügen. Um eine Zeichenfolge zu codieren, können Sie das Modul URI::Escape verwenden. Die uri_escape Funktion gibt die Escape-Sequenzen:

my $original = "Colon : Hash # Percent %"; 

my $escaped = uri_escape($original); 

print "$escaped\n"; # 'Colon%20%3A%20Hash%20%23%20Percent%20%25' 

die Zeichenfolge entschlüsseln, verwenden Sie die uri_unescape Funktion:

my $unescaped = uri_unescape($escaped); 

print $unescaped; # back to original 

Wenn Sie es selbst tun wollen, geben Sie einfach die reservierten Zeichen ersetzen müssen mit ihrem Kodierungen. Eine globale Substitution ist eine Möglichkeit, es zu tun:

# 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

Mark Stosberg hat einen entsprechenden Blog-Eintrag: http://mark.stosberg.com/blog/2010/12/percent-encoding- uris-in-perl.html zum Thema. –

1

DIY kodieren (oben Version zu verbessern):

$string =~ s/([^^A-Za-z0-9\-_.!~*'()])/ sprintf "%%%02x", ord $1 /eg; 

(beachten Sie die '% 02x' und nicht nur '% 0x')

DIY decode (Zusatz '+' -> ' ‚):

$string =~ s/\+/ /g; $string =~ s/%([A-Fa-f\d]{2})/chr hex $1/eg; 

Coder Coder helfen - bartering Wissen!

1

Vielleicht wird dies helfen zu entscheiden, welche Methode zu wählen.

Benchmarks auf Perl 5.22.1. Jede Funktion gibt dasselbe Ergebnis für $string zurück.

Code:

#!/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); 
    }, 
}); 

und Ergebnisse:

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

Es gibt ein großes Problem mit diesem Test: Jede Iteration modifiziert die globale $ -Zeichenfolge und macht mehr Arbeit für die nächste Iteration. So haben 'a' und 'b' weniger Arbeit als 'c' und 'd'. Versuchen Sie, die Länge ($ string) zu drucken, nachdem cmpthese() fertig ist. – TheAmigo