The perl1 version of this perl5 code
sub UnEscape { my $str = shift; $str =~ s/%(\w\w)/sprintf("%c", hex($1))/eg; $str; }
Is something like the following. Note how substr isn't quite as nice as you'd expect.
sub UnEscape { $str = $_[0]; $pos = index($str, '%'); while ($pos != -1) { $code = sprintf("%c", hex(substr($str, $pos + 1, 2))); $str = substr($str, 0, $pos).$code.substr($str, $pos + 3, length($str)); $pos = index($str, '%'); } $str; }
everywhere, if your result was a "%" character, you would end up doubly decoding it. You should be using the position of the next occurence of "%" substring, thus, continue from after the previous value of $pos, instead of starting again from the start of the string.$pos = index($str, '%');
I have no idea if substr() in this ancient version of the language could actually handle that.
Tested with:sub ue {
$str = $_[0];
while ($str =~/%(\w\w)/) {
$s = sprintf('%c', hex($1));
$str =~ s/%\w\w/$s/;
}
$str;
}
Works in perl 1.0_15 and perl 5.8.0print do ue("%41%20%42%20%43");
print "\n";
Re:s///ge
Juerd on 2003-07-05T23:34:10
To deal with the problem that bart describes, you need to re-build the string entirely.Tested with:sub ue {
$in = $_[0]; $out = '';
while ($in =~ s/%(\w\w)|([^%]+)//) {
$out.= ($1 ? sprintf('%c', hex($1)) : $2);
$1 = $2 = '';
}
$out;
}No longer works with recent Perls, because those don't allow clearing $n manually. In Perl 1, you had to, because otherwise, $1 would not be cleared if only the second group matched!print do ue("%41%2541%20%42%20%43");
print "\n";
To make it work with Perl 5.8.0 again, we need to eval that part. Eval STRING, because Perl 1 had no eval BLOCK.sub ue {
$in = $_[0]; $out = '';
while ($in =~ s/%(\w\w)|([^%]+)//) {
$out.= ($1 ? sprintf('%c', hex($1)) : $2);
eval "\$1 = \$2 = '';";
}
$out;
}