Would it work if you used a regex to turn any but a list of "safe" characters into escaped hexadecimals - the following, which I have cribbed from the otherwise annoying
CGI Programming with Perl, may be what you want:
$dirty_string =~ s/([^a-zA-Z0-9_.!~() -])/sprintf "%%%02X", ord($1)/ei
+;
You could then translate them back at your leisure.
§
George Sherston