Welcome, guest | Sign In | My Account | Store | Cart

URL encode and decode functions for Perl.

Perl, 13 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
sub urlencode {
    my $s = shift;
    $s =~ s/ /+/g;
    $s =~ s/([^A-Za-z0-9\+-])/sprintf("%%%02X", ord($1))/seg;
    return $s;
}

sub urldecode {
    my $s = shift;
    $s =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/seg;
    $s =~ s/\+/ /g;
    return $s;
}

6 comments

Egor Korablev 13 years, 3 months ago  # | flag

We have CPAN:

use URI::Escape;
hawk 11 years, 6 months ago  # | flag

CPAN!? Seriously? You want me to load an entire CPAN module for just 5 lines of code!? No wonder there is so much code bloat out there!

Thank you Trent! Quick. Clean. Efficient.

Michael Jacob 11 years, 5 months ago  # | flag

Yes, Quick, Clean, Wrong.

print urldecode(urlencode('1 + 1 = 2'));
1   1 = 2
Janis Slapins 11 years, 5 months ago  # | flag

That's almost the same as used in URI::Escape.pm except '/chr(hex($1))/eg' instead of '/pack .../seg'.

Corwin Brust 11 years ago  # | flag

Speaking up for Egor's point here:

  • someone else writes and tests the algorithm
  • fixes will be make available (you don't have to try to get your own hard won life lessons into each copy of each program that uses the code.
  • any idea how the five line solution will handle unicode? Me either, but I suspect that if URI::Escape has problems in the regard you will find out about them on RT: https://rt.perl.org/rt3//Public/Search/Simple.html?q=URI%3A%3AEscape

Generalizing, it's a pretty good ideal to package up all but the most trivial solutions. For me, that's anything that doesn't make a good alias for SH. Posting to CPAN may or may not make sense, but it's worth thinking about whether having others review, test and potentially even improve your code will help your projects in the long term.

S Vertigan 8 years, 8 months ago  # | flag

I can confirm this code is broken in regard to the + character however there is a 3 line solution in the webmin libraries that works just fine (even with unicode).

sub urlize {
my ($rv) = @_;
$rv =~ s/([^A-Za-z0-9])/sprintf("%%%2.2X", ord($1))/ge;
return $rv;
}

sub un_urlize {
my ($rv) = @_;
$rv =~ s/\+/ /g;
$rv =~ s/%(..)/pack("c",hex($1))/ge;
return $rv;
}

Passing the string '1 + 1 = 2' to urlencode returns '1+++1+%3D+2', where urlize returned '1%20%2B%201%20%3D%202'.

Created by Trent Mick on Tue, 2 Nov 2010 (MIT)
Perl recipes (17)
Trent Mick's recipes (28)

Required Modules

  • (none specified)

Other Information and Tasks