The anonymous regex could be better written:
$data =~ s/%[0-9a-fA-F]{2}/pack('c', hex($1)/eg; I believe.
The difference is that, his first translates all + characters into spaces. His also only grabs two valid hexadecimal characters following a percentage sign, while your regex matches two of any characters (besides a new line) following a percentage sign. It's probably better to be more specific. Still, btrott is right. Using CGI.pm is the way to go.