URL decoding: Difference between revisions
added php |
Langurmonkey (talk | contribs) |
||
(206 intermediate revisions by more than 100 users not shown) | |||
Line 1: | Line 1: | ||
{{task}} |
|||
{{task}}[[Category:String manipulation]] |
|||
[[Category:String manipulation]] |
|||
This task (the reverse of [[URL encoding]]) is to provide a function or mechanism to convert a url-encoded string into its original unencoded form. |
|||
This task (the reverse of [[URL encoding]] and distinct from [[URL parser]]) is to provide a function |
|||
'''Example''' |
|||
or mechanism to convert an URL-encoded string into its original unencoded form. |
|||
The encoded string "<code><nowiki>http%3A%2F%2Ffoo%20bar%2F</nowiki></code>" should be reverted to the unencoded form "<code><nowiki>http://foo bar/</nowiki></code>". |
|||
;Test cases: |
|||
* The encoded string "<code><nowiki>http%3A%2F%2Ffoo%20bar%2F</nowiki></code>" should be reverted to the unencoded form "<code><nowiki>http://foo bar/</nowiki></code>". |
|||
* The encoded string "<code><nowiki>google.com/search?q=%60Abdu%27l-Bah%C3%A1</nowiki></code>" should revert to the unencoded form "<code><nowiki>google.com/search?q=`Abdu'l-Bahá</nowiki></code>". |
|||
* The encoded string "<code><nowiki>%25%32%35</nowiki></code>" should revert to the unencoded form "<code><nowiki>%25</nowiki></code>" and '''not''' "<code><nowiki>%</nowiki></code>". |
|||
<br><br> |
|||
=={{header|11l}}== |
|||
<syntaxhighlight lang="11l">F url_decode(s) |
|||
V r = ‘’ |
|||
V i = 0 |
|||
L i < s.len |
|||
I s[i] == ‘%’ |
|||
[Byte] b |
|||
L i < s.len & s[i] == ‘%’ |
|||
i++ |
|||
b.append(Int(s[i.+2], radix' 16)) |
|||
i += 2 |
|||
r ‘’= b.decode(‘utf-8’) |
|||
E |
|||
r ‘’= s[i] |
|||
i++ |
|||
R r |
|||
print(url_decode(‘http%3A%2F%2Ffoo%20bar%2F’)) |
|||
print(url_decode(‘https://ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%B0%D0%BD%D1%81%D0%BF%D0%B0%D0%B9%D0%BB%D0%B5%D1%80’))</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
https://ru.wikipedia.org/wiki/Транспайлер |
|||
</pre> |
|||
=={{header|ABAP}}== |
|||
<syntaxhighlight lang="abap">REPORT Z_DECODE_URL. |
|||
DATA: lv_encoded_url TYPE string VALUE 'http%3A%2F%2Ffoo%20bar%2F', |
|||
lv_decoded_url TYPE string. |
|||
CALL METHOD CL_HTTP_UTILITY=>UNESCAPE_URL |
|||
EXPORTING |
|||
ESCAPED = lv_encoded_url |
|||
RECEIVING |
|||
UNESCAPED = lv_decoded_url. |
|||
WRITE: 'Encoded URL: ', lv_encoded_url, /, 'Decoded URL: ', lv_decoded_url.</syntaxhighlight> |
|||
=={{header|Action!}}== |
|||
<syntaxhighlight lang="action!">PROC Append(CHAR ARRAY s CHAR c) |
|||
s(0)==+1 |
|||
s(s(0))=c |
|||
RETURN |
|||
CHAR FUNC GetCharFromHex(CHAR c1,c2) |
|||
CHAR ARRAY hex=['0 '1 '2 '3 '4 '5 '6 '7 '8 '9 'A 'B 'C 'D 'E 'F] |
|||
BYTE i,res |
|||
res=0 |
|||
FOR i=0 TO 15 |
|||
DO |
|||
IF c1=hex(i) THEN res==+i LSH 4 FI |
|||
IF c2=hex(i) THEN res==+i FI |
|||
OD |
|||
RETURN (res) |
|||
PROC Decode(CHAR ARRAY in,out) |
|||
BYTE i |
|||
CHAR c |
|||
out(0)=0 |
|||
i=1 |
|||
WHILE i<=in(0) |
|||
DO |
|||
c=in(i) |
|||
i==+1 |
|||
IF c='+ THEN |
|||
Append(out,' ) |
|||
ELSEIF c='% THEN |
|||
c=GetCharFromHex(in(i),in(i+1)) |
|||
i==+2 |
|||
Append(out,c) |
|||
ELSE |
|||
Append(out,c) |
|||
FI |
|||
OD |
|||
RETURN |
|||
PROC PrintInv(CHAR ARRAY a) |
|||
BYTE i |
|||
IF a(0)>0 THEN |
|||
FOR i=1 TO a(0) |
|||
DO |
|||
Put(a(i)%$80) |
|||
OD |
|||
FI |
|||
RETURN |
|||
PROC Test(CHAR ARRAY in) |
|||
CHAR ARRAY out(256) |
|||
PrintInv("input ") |
|||
PrintF(" %S%E",in) |
|||
Decode(in,out) |
|||
PrintInv("decoded") |
|||
PrintF(" %S%E%E",out) |
|||
RETURN |
|||
PROC Main() |
|||
Test("http%3A%2F%2Ffoo%20bar%2F") |
|||
Test("http%3A%2F%2Ffoo+bar%2F*_-.html") |
|||
RETURN</syntaxhighlight> |
|||
{{out}} |
|||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/URL_decoding.png Screenshot from Atari 8-bit computer] |
|||
<pre> |
|||
input http%3A%2F%2Ffoo%20bar%2F |
|||
decoded http://foo bar/ |
|||
input http%3A%2F%2Ffoo+bar%2F*_-.html |
|||
decoded http://foo bar/*_-.html |
|||
</pre> |
|||
=={{header|Ada}}== |
|||
{{libheader|AWS}} |
|||
<syntaxhighlight lang="ada">with AWS.URL; |
|||
with Ada.Text_IO; use Ada.Text_IO; |
|||
procedure Decode is |
|||
Encoded : constant String := "http%3A%2F%2Ffoo%20bar%2F"; |
|||
begin |
|||
Put_Line (AWS.URL.Decode (Encoded)); |
|||
end Decode; |
|||
</syntaxhighlight> |
|||
Without external libraries: |
|||
<syntaxhighlight lang="ada">package URL is |
|||
function Decode (URL : in String) return String; |
|||
end URL;</syntaxhighlight> |
|||
<syntaxhighlight lang="ada">package body URL is |
|||
function Decode (URL : in String) return String is |
|||
Buffer : String (1 .. URL'Length); |
|||
Filled : Natural := 0; |
|||
Position : Positive := URL'First; |
|||
begin |
|||
while Position in URL'Range loop |
|||
Filled := Filled + 1; |
|||
case URL (Position) is |
|||
when '+' => |
|||
Buffer (Filled) := ' '; |
|||
Position := Position + 1; |
|||
when '%' => |
|||
Buffer (Filled) := |
|||
Character'Val |
|||
(Natural'Value |
|||
("16#" & URL (Position + 1 .. Position + 2) & "#")); |
|||
Position := Position + 3; |
|||
when others => |
|||
Buffer (Filled) := URL (Position); |
|||
Position := Position + 1; |
|||
end case; |
|||
end loop; |
|||
return Buffer (1 .. Filled); |
|||
end Decode; |
|||
end URL;</syntaxhighlight> |
|||
<syntaxhighlight lang="ada">with Ada.Command_Line, |
|||
Ada.Text_IO; |
|||
with URL; |
|||
procedure Test_URL_Decode is |
|||
use Ada.Command_Line, Ada.Text_IO; |
|||
begin |
|||
if Argument_Count = 0 then |
|||
Put_Line (URL.Decode ("http%3A%2F%2Ffoo%20bar%2F")); |
|||
else |
|||
for I in 1 .. Argument_Count loop |
|||
Put_Line (URL.Decode (Argument (I))); |
|||
end loop; |
|||
end if; |
|||
end Test_URL_Decode;</syntaxhighlight> |
|||
=={{header|ALGOL 68}}== |
|||
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}} |
|||
Note: See the discussion page re displaying the results (which is mostly focused on the AWK solution but will apply elsewhere too). |
|||
<br> |
|||
For the second task example, this outputs the encoded UTF-8 characters, what you see depends on what you look at it with... |
|||
<syntaxhighlight lang="algol68"># returns c decoded as a hex digit # |
|||
PROC hex value = ( CHAR c )INT: IF c >= "0" AND c <= "9" THEN ABS c - ABS "0" |
|||
ELIF c >= "A" AND c <= "F" THEN 10 + ( ABS c - ABS "A" ) |
|||
ELSE 10 + ( ABS c - ABS "a" ) |
|||
FI; |
|||
# returns the URL encoded string decoded - minimal error handling # |
|||
PROC url decode = ( STRING encoded )STRING: |
|||
BEGIN |
|||
[ LWB encoded : UPB encoded ]CHAR result; |
|||
INT result pos := LWB encoded; |
|||
INT pos := LWB encoded; |
|||
INT max pos := UPB encoded; |
|||
INT max encoded := max pos - 3; |
|||
WHILE pos <= UPB encoded |
|||
DO |
|||
IF encoded[ pos ] /= "%" AND pos <= max encoded |
|||
THEN |
|||
# not a coded character # |
|||
result[ result pos ] := encoded[ pos ]; |
|||
pos +:= 1 |
|||
ELSE |
|||
# have an encoded character # |
|||
result[ result pos ] := REPR ( ( 16 * hex value( encoded[ pos + 1 ] ) ) |
|||
+ hex value( encoded[ pos + 2 ] ) |
|||
); |
|||
pos +:= 3 |
|||
FI; |
|||
result pos +:= 1 |
|||
OD; |
|||
result[ LWB result : result pos - 1 ] |
|||
END # url decode # ; |
|||
# test the url decode procedure # |
|||
print( ( url decode( "http%3A%2F%2Ffoo%20bar%2F" ), newline ) ); |
|||
print( ( url decode( "google.com/search?q=%60Abdu%27l-Bah%C3%A1" ), newline ) )</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
|||
=={{header|Apex}}== |
|||
<syntaxhighlight lang="apex">EncodingUtil.urlDecode('http%3A%2F%2Ffoo%20bar%2F', 'UTF-8'); |
|||
EncodingUtil.urlDecode('google.com/search?q=%60Abdu%27l-Bah%C3%A1', 'UTF-8');</syntaxhighlight> |
|||
<pre>http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá</pre> |
|||
=={{header|AppleScript}}== |
|||
{{libheader|AppleScript Toolbox}} |
|||
<syntaxhighlight lang="applescript">AST URL decode "google.com/search?q=%60Abdu%27l-Bah%C3%A1"</syntaxhighlight> |
|||
=={{header|Arturo}}== |
|||
<syntaxhighlight lang="rebol">print decode.url "http%3A%2F%2Ffoo%20bar%2F" |
|||
print decode.url "google.com/search?q=%60Abdu%27l-Bah%C3%A1"</syntaxhighlight> |
|||
{{out}} |
|||
<pre>http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá</pre> |
|||
=={{header|AutoHotkey}}== |
|||
<syntaxhighlight lang="autohotkey"> |
|||
UriDecode(Uri) { |
|||
LoopOffset := 0 |
|||
VarLength := 0 |
|||
VarSetCapacity(Var, StrPut(Uri, "UTF-8"), 0) |
|||
Loop Parse, Uri |
|||
{ |
|||
If (A_Index < LoopOffset) { |
|||
Continue |
|||
} |
|||
If (A_LoopField = Chr(37)) { |
|||
Number := "0x" . SubStr(Uri, A_Index + 1, 2) |
|||
LoopOffset := A_Index + 3 |
|||
} |
|||
Else { |
|||
Number := Ord(A_LoopField) |
|||
} |
|||
NumPut(Number, Var, VarLength++, "UChar") |
|||
} |
|||
Return StrGet(&Var, VarLength, "UTF-8") |
|||
} |
|||
MsgBox % UriDecode("http%3A%2F%2Ffoo%20bar%2F") |
|||
MsgBox % UriDecode("google.com/search?q=%60Abdu%27l-Bah%C3%A1") |
|||
MsgBox % UriDecode("%25%32%35") |
|||
</syntaxhighlight> |
|||
=={{header|AWK}}== |
|||
<syntaxhighlight lang="awk"> |
|||
# syntax: |
|||
awk ' |
|||
BEGIN { |
|||
str = "http%3A%2F%2Ffoo%20bar%2F" # "http://foo bar/" |
|||
printf("%s\n",str) |
|||
len=length(str) |
|||
for (i=1;i<=len;i++) { |
|||
if ( substr(str,i,1) == "%") { |
|||
L = substr(str,1,i-1) # chars to left of "%" |
|||
M = substr(str,i+1,2) # 2 chars to right of "%" |
|||
R = substr(str,i+3) # chars to right of "%xx" |
|||
str = sprintf("%s%c%s",L,hex2dec(M),R) |
|||
} |
|||
} |
|||
printf("%s\n",str) |
|||
exit(0) |
|||
} |
|||
function hex2dec(s, num) { |
|||
num = index("0123456789ABCDEF",toupper(substr(s,length(s)))) - 1 |
|||
sub(/.$/,"",s) |
|||
return num + (length(s) ? 16*hex2dec(s) : 0) |
|||
} ' |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http%3A%2F%2Ffoo%20bar%2F |
|||
http://foo bar/ |
|||
</pre> |
|||
OR: |
|||
<syntaxhighlight lang="awk"> |
|||
LC_ALL=C |
|||
echo "http%3A%2F%2Ffoo%20bar%2F" | gawk -vRS='%[[:xdigit:]]{2}' ' |
|||
RT {RT = sprintf("%c",strtonum("0x" substr(RT, 2)))} |
|||
{gsub(/+/," ");printf "%s", $0 RT}' |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
</pre> |
|||
=={{header|BaCon}}== |
|||
<syntaxhighlight lang="freebasic">FUNCTION Url_Decode$(url$) |
|||
LOCAL result$ |
|||
SPLIT url$ BY "%" TO item$ SIZE total |
|||
FOR x = 1 TO total-1 |
|||
result$ = result$ & CHR$(DEC(LEFT$(item$[x], 2))) & MID$(item$[x], 3) |
|||
NEXT |
|||
RETURN item$[0] & result$ |
|||
END FUNCTION |
|||
PRINT Url_Decode$("http%3A%2F%2Ffoo%20bar%2F") |
|||
PRINT Url_Decode$("google.com/search?q=%60Abdu%27l-Bah%C3%A1")</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
|||
=={{header|Bash}}== |
|||
See [[#UNIX Shell]] |
|||
=={{header|BBC BASIC}}== |
|||
{{works with|BBC BASIC for Windows}} |
|||
<syntaxhighlight lang="bbcbasic"> PRINT FNurldecode("http%3A%2F%2Ffoo%20bar%2F") |
|||
END |
|||
DEF FNurldecode(url$) |
|||
LOCAL i% |
|||
REPEAT |
|||
i% = INSTR(url$, "%", i%+1) |
|||
IF i% THEN |
|||
url$ = LEFT$(url$,i%-1) + \ |
|||
\ CHR$EVAL("&"+FNupper(MID$(url$,i%+1,2))) + \ |
|||
\ MID$(url$,i%+3) |
|||
ENDIF |
|||
UNTIL i% = 0 |
|||
= url$ |
|||
DEF FNupper(A$) |
|||
LOCAL A%,C% |
|||
FOR A% = 1 TO LEN(A$) |
|||
C% = ASCMID$(A$,A%) |
|||
IF C% >= 97 IF C% <= 122 MID$(A$,A%,1) = CHR$(C%-32) |
|||
NEXT |
|||
= A$</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
</pre> |
|||
=={{header|Bracmat}}== |
|||
<syntaxhighlight lang="bracmat">( ( decode |
|||
= decoded hexcode notencoded |
|||
. :?decoded |
|||
& whl |
|||
' ( @(!arg:?notencoded "%" (% %:?hexcode) ?arg) |
|||
& !decoded !notencoded chr$(x2d$!hexcode):?decoded |
|||
) |
|||
& str$(!decoded !arg) |
|||
) |
|||
& out$(decode$http%3A%2F%2Ffoo%20bar%2F) |
|||
);</syntaxhighlight> |
|||
{{out}} |
|||
<pre>http://foo bar/</pre> |
|||
=={{header|C}}== |
|||
<syntaxhighlight lang="c">#include <stdio.h> |
|||
#include <string.h> |
|||
inline int ishex(int x) |
|||
{ |
|||
return (x >= '0' && x <= '9') || |
|||
(x >= 'a' && x <= 'f') || |
|||
(x >= 'A' && x <= 'F'); |
|||
} |
|||
int decode(const char *s, char *dec) |
|||
{ |
|||
char *o; |
|||
const char *end = s + strlen(s); |
|||
int c; |
|||
for (o = dec; s <= end; o++) { |
|||
c = *s++; |
|||
if (c == '+') c = ' '; |
|||
else if (c == '%' && ( !ishex(*s++) || |
|||
!ishex(*s++) || |
|||
!sscanf(s - 2, "%2x", &c))) |
|||
return -1; |
|||
if (dec) *o = c; |
|||
} |
|||
return o - dec; |
|||
} |
|||
int main() |
|||
{ |
|||
const char *url = "http%3A%2F%2ffoo+bar%2fabcd"; |
|||
char out[strlen(url) + 1]; |
|||
printf("length: %d\n", decode(url, 0)); |
|||
puts(decode(url, out) < 0 ? "bad string" : out); |
|||
return 0; |
|||
}</syntaxhighlight> |
|||
=={{header|C sharp}}== |
|||
<syntaxhighlight lang="csharp">using System; |
|||
namespace URLEncode |
|||
{ |
|||
internal class Program |
|||
{ |
|||
private static void Main(string[] args) |
|||
{ |
|||
Console.WriteLine(Decode("http%3A%2F%2Ffoo%20bar%2F")); |
|||
} |
|||
private static string Decode(string uri) |
|||
{ |
|||
return Uri.UnescapeDataString(uri); |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
</pre> |
|||
=={{header|C++}}== |
|||
{{libheader|Poco}} |
|||
{{works with|g++}} |
|||
<syntaxhighlight lang="cpp">#include <string> |
|||
#include "Poco/URI.h" |
|||
#include <iostream> |
|||
int main( ) { |
|||
std::string encoded( "http%3A%2F%2Ffoo%20bar%2F" ) ; |
|||
std::string decoded ; |
|||
Poco::URI::decode ( encoded , decoded ) ; |
|||
std::cout << encoded << " is decoded: " << decoded << " !" << std::endl ; |
|||
return 0 ; |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>http%3A%2F%2Ffoo%20bar%2F is decoded: http://foo bar/ !</pre> |
|||
=={{header|Caché ObjectScript}}== |
|||
<pre>USER>Write $ZConvert("http%3A%2F%2Ffoo%20bar%2F", "I", "URL") |
|||
http://foo bar/</pre> |
|||
=={{header|Clojure}}== |
|||
<syntaxhighlight lang="clojure">(java.net.URLDecoder/decode "http%3A%2F%2Ffoo%20bar%2F")</syntaxhighlight> |
|||
=={{header|CoffeeScript}}== |
|||
<syntaxhighlight lang="coffeescript"> |
|||
console.log decodeURIComponent "http%3A%2F%2Ffoo%20bar%2F?name=Foo%20Barson" |
|||
</syntaxhighlight> |
|||
<syntaxhighlight lang="text"> |
|||
> coffee foo.coffee |
|||
http://foo bar/?name=Foo Barson |
|||
</syntaxhighlight> |
|||
=={{header|Common Lisp}}== |
|||
<syntaxhighlight lang="lisp">(defun decode (string &key start) |
|||
(assert (char= (char string start) #\%)) |
|||
(if (>= (length string) (+ start 3)) |
|||
(multiple-value-bind (code pos) |
|||
(parse-integer string :start (1+ start) :end (+ start 3) :radix 16 :junk-allowed t) |
|||
(if (= pos (+ start 3)) |
|||
(values (code-char code) pos) |
|||
(values #\% (1+ start)))) |
|||
(values #\% (1+ start)))) |
|||
(defun url-decode (url) |
|||
(loop with start = 0 |
|||
for pos = (position #\% url :start start) |
|||
collect (subseq url start pos) into chunks |
|||
when pos |
|||
collect (multiple-value-bind (decoded next) (decode url :start pos) |
|||
(setf start next) |
|||
(string decoded)) |
|||
into chunks |
|||
while pos |
|||
finally (return (apply #'concatenate 'string chunks)))) |
|||
(url-decode "http%3A%2F%2Ffoo%20bar%2F")</syntaxhighlight> |
|||
{{out}} |
|||
<pre>"http://foo bar/"</pre> |
|||
=={{header|Crystal}}== |
|||
<syntaxhighlight lang="crystal">require "uri" |
|||
puts URI.decode "http%3A%2F%2Ffoo%20bar%2F" |
|||
puts URI.decode "google.com/search?q=%60Abdu%27l-Bah%C3%A1"</syntaxhighlight> |
|||
{{out}} |
|||
<pre>http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá</pre> |
|||
=={{header|D}}== |
|||
<syntaxhighlight lang="d">import std.stdio, std.uri; |
|||
void main() { |
|||
writeln(decodeComponent("http%3A%2F%2Ffoo%20bar%2F")); |
|||
}</syntaxhighlight> |
|||
<pre>http://foo bar/</pre> |
|||
=={{header|Delphi}}== |
=={{header|Delphi}}== |
||
< |
<syntaxhighlight lang="delphi">program URLEncoding; |
||
{$APPTYPE CONSOLE} |
{$APPTYPE CONSOLE} |
||
Line 15: | Line 558: | ||
begin |
begin |
||
Writeln(TIdURI.URLDecode('http%3A%2F%2Ffoo%20bar%2F')); |
Writeln(TIdURI.URLDecode('http%3A%2F%2Ffoo%20bar%2F')); |
||
end.</ |
end.</syntaxhighlight> |
||
=={{header|Elixir}}== |
|||
<syntaxhighlight lang="elixir">IO.inspect URI.decode("http%3A%2F%2Ffoo%20bar%2F") |
|||
IO.inspect URI.decode("google.com/search?q=%60Abdu%27l-Bah%C3%A1")</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
"http://foo bar/" |
|||
"google.com/search?q=`Abdu'l-Bahá" |
|||
</pre> |
|||
=={{header|Erlang}}== |
|||
Built in. |
|||
<pre> |
|||
34> http_uri:decode("http%3A%2F%2Ffoo%20bar%2F"). |
|||
"http://foo bar/" |
|||
</pre> |
|||
=={{header|F_Sharp|F#}}== |
|||
{{trans|C#}} |
|||
<syntaxhighlight lang="fsharp">open System |
|||
let decode uri = Uri.UnescapeDataString(uri) |
|||
[<EntryPoint>] |
|||
let main argv = |
|||
printfn "%s" (decode "http%3A%2F%2Ffoo%20bar%2F") |
|||
0</syntaxhighlight> |
|||
=={{header|Factor}}== |
|||
<syntaxhighlight lang="factor">USING: io kernel urls.encoding ; |
|||
IN: rosetta-code.url-decoding |
|||
"http%3A%2F%2Ffoo%20bar%2F" |
|||
"google.com/search?q=%60Abdu%27l-Bah%C3%A1" |
|||
[ url-decode print ] bi@</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
|||
=={{header|Free Pascal}}== |
|||
<syntaxhighlight lang="pascal">function urlDecode(data: String): AnsiString; |
|||
var |
|||
ch: Char; |
|||
pos, skip: Integer; |
|||
begin |
|||
pos := 0; |
|||
skip := 0; |
|||
Result := ''; |
|||
for ch in data do begin |
|||
if skip = 0 then begin |
|||
if (ch = '%') and (pos < data.length -2) then begin |
|||
skip := 2; |
|||
Result := Result + AnsiChar(Hex2Dec('$' + data[pos+2] + data[pos+3])); |
|||
end else begin |
|||
Result := Result + ch; |
|||
end; |
|||
end else begin |
|||
skip := skip - 1; |
|||
end; |
|||
pos := pos +1; |
|||
end; |
|||
end;</syntaxhighlight> |
|||
=={{header|FreeBASIC}}== |
|||
{{trans|Liberty BASIC}} |
|||
{{trans|Pascal}} |
|||
<syntaxhighlight lang="freebasic"> |
|||
Const alphanum = "0123456789abcdefghijklmnopqrstuvwxyz" |
|||
Function ToDecimal (cadena As String, base_ As Uinteger) As Uinteger |
|||
Dim As Uinteger i, n, result = 0 |
|||
Dim As Uinteger inlength = Len(cadena) |
|||
For i = 1 To inlength |
|||
n = Instr(alphanum, Mid(Lcase(cadena),i,1)) - 1 |
|||
n *= (base_^(inlength-i)) |
|||
result += n |
|||
Next |
|||
Return result |
|||
End Function |
|||
Function url2string(cadena As String) As String |
|||
Dim As String c, nc, res |
|||
For j As Integer = 1 To Len(cadena) |
|||
c = Mid(cadena, j, 1) |
|||
If c = "%" Then |
|||
nc = Chr(ToDecimal((Mid(cadena, j+1, 2)), 16)) |
|||
res &= nc |
|||
j += 2 |
|||
Else |
|||
res &= c |
|||
End If |
|||
Next j |
|||
Return res |
|||
End Function |
|||
Dim As String URL = "http%3A%2F%2Ffoo%20bar%2F" |
|||
Print "Supplied URL '"; URL; "'" |
|||
Print "URL decoding '"; url2string(URL); "'" |
|||
URL = "google.com/search?q=%60Abdu%27l-Bah%C3%A1" |
|||
Print !"\nSupplied URL '"; URL; "'" |
|||
Print "URL decoding '"; url2string(URL); "'" |
|||
Sleep |
|||
</syntaxhighlight> |
|||
=={{header|Frink}}== |
|||
While the default is to decode parameters as UTF-8 (which is the W3C recommendation,) the characters may have been encoded in another encoding scheme, and this can be handled correctly. |
|||
<syntaxhighlight lang="frink">URLDecode["google.com/search?q=%60Abdu%27l-Bah%C3%A1","UTF8"]</syntaxhighlight> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
"os" |
|||
"fmt" |
"fmt" |
||
" |
"log" |
||
"net/url" |
|||
) |
) |
||
func main() { |
func main() { |
||
for _, escaped := range []string{ |
|||
url, err := http.URLUnescape("http%3A%2F%2Ffoo%20bar%2F") |
|||
"http%3A%2F%2Ffoo%20bar%2F", |
|||
if err != nil { |
|||
"google.com/search?q=%60Abdu%27l-Bah%C3%A1", |
|||
fmt.Println(err) |
|||
} { |
|||
os.Exit(1) |
|||
u, err := url.QueryUnescape(escaped) |
|||
if err != nil { |
|||
log.Println(err) |
|||
continue |
|||
} |
|||
fmt.Println(u) |
|||
} |
} |
||
}</syntaxhighlight> |
|||
fmt.Println(url) |
|||
{{out}} |
|||
}</lang> |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
|||
=={{header|Groovy}}== |
|||
<syntaxhighlight lang="groovy">assert URLDecoder.decode('http%3A%2F%2Ffoo%20bar%2F') == 'http://foo bar/'</syntaxhighlight> |
|||
=={{header|Haskell}}== |
|||
<syntaxhighlight lang="haskell">import qualified Data.Char as Char |
|||
urlDecode :: String -> Maybe String |
|||
urlDecode [] = Just [] |
|||
urlDecode ('%':xs) = |
|||
case xs of |
|||
(a:b:xss) -> |
|||
urlDecode xss |
|||
>>= return . ((Char.chr . read $ "0x" ++ [a,b]) :) |
|||
_ -> Nothing |
|||
urlDecode ('+':xs) = urlDecode xs >>= return . (' ' :) |
|||
urlDecode (x:xs) = urlDecode xs >>= return . (x :) |
|||
main :: IO () |
|||
main = putStrLn . maybe "Bad decode" id $ urlDecode "http%3A%2F%2Ffoo%20bar%2F"</syntaxhighlight> |
|||
{{out}} |
|||
<pre>http://foo bar/</pre> |
|||
Another approach: |
|||
<syntaxhighlight lang="haskell">import Data.Char (chr) |
|||
import Data.List.Split (splitOn) |
|||
deCode :: String -> String |
|||
deCode url = |
|||
let ps = splitOn "%" url |
|||
in concat $ |
|||
head ps : |
|||
((\(a, b) -> (chr . read) (mappend "0x" a) : b) <$> (splitAt 2 <$> tail ps)) |
|||
-- TEST ------------------------------------------------------------------------ |
|||
main :: IO () |
|||
main = putStrLn $ deCode "http%3A%2F%2Ffoo%20bar%2F"</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>http://foo bar/</pre> |
|||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
< |
<syntaxhighlight lang="icon">link hexcvt |
||
procedure main() |
procedure main() |
||
Line 57: | Line 769: | ||
else move(1) |
else move(1) |
||
return c |
return c |
||
end</ |
end</syntaxhighlight> |
||
{{libheader|Icon Programming Library}} |
{{libheader|Icon Programming Library}} |
||
[http://www.cs.arizona.edu/icon/library/src/procs/hexcvt.icn hexcvt provides hexstring] |
[http://www.cs.arizona.edu/icon/library/src/procs/hexcvt.icn hexcvt provides hexstring] |
||
{{out}} |
|||
Output:<pre>encoded = "http%3A%2F%2Ffoo%20bar%2F" |
|||
<pre>encoded = "http%3A%2F%2Ffoo%20bar%2F" |
|||
decoded = "http://foo bar/"</pre> |
decoded = "http://foo bar/"</pre> |
||
=={{header|J}}== |
=={{header|J}}== |
||
J does not have a native urldecode (until version 7 when jhs includes a jurldecode). |
J does not have a native urldecode (until version 7 when the <code>jhs</code> ide addon includes a jurldecode). |
||
Here is an implementation: |
Here is an implementation: |
||
< |
<syntaxhighlight lang="j">require'strings convert' |
||
urldecode=: rplc&(;"_1&a."2(,:tolower)'%',.hfd i.#a.)</ |
urldecode=: rplc&(~.,/;"_1&a."2(,:tolower)'%',.toupper hfd i.#a.)</syntaxhighlight> |
||
Example use: |
Example use: |
||
< |
<syntaxhighlight lang="j"> urldecode 'http%3A%2F%2Ffoo%20bar%2F' |
||
http://foo bar/</ |
http://foo bar/</syntaxhighlight> |
||
Note that an earlier implementation assumed the j6 implementation of <code>hfd</code> which where hexadecimal letters resulting from <code>hfd</code> were upper case. J8, in contrast, provides a lower case result from hfd. The addition of <code>toupper</code> guarantees the case insensitivity required by [http://tools.ietf.org/html/rfc3986#section-2.1 RFC 3986] regardless of which version of J you are using. As the parenthesized expression containing <code>hfd</code> is only evaluated at definition time, there's no performance penalty from the use of <code>toupper</code>. |
|||
Note that a minor efficiency improvement is possible, by eliminating duplicated escape codes: |
|||
<lang j>urldecode=: rplc&(~.,/;"_1&a."2(,:tolower)'%',.hfd i.#a.)</lang> |
|||
Example use: |
|||
<syntaxhighlight lang="j"> urldecode 'google.com/search?q=%60Abdu%27l-Bah%C3%A1' |
|||
google.com/search?q=`Abdu'l-Bahá</syntaxhighlight> |
|||
=={{header|Java}}== |
|||
Java offers the ''URLDecoder'' and ''URLEncoder'' classes for this specific task. |
|||
<syntaxhighlight lang="java"> |
|||
import java.net.URLDecoder; |
|||
import java.nio.charset.StandardCharsets; |
|||
</syntaxhighlight> |
|||
<syntaxhighlight lang="java"> |
|||
URLDecoder.decode("http%3A%2F%2Ffoo%20bar%2F", StandardCharsets.UTF_8) |
|||
</syntaxhighlight> |
|||
Alternately, you could use a regular expression capture |
|||
<syntaxhighlight lang="java"> |
|||
import java.util.regex.Matcher; |
|||
import java.util.regex.Pattern; |
|||
</syntaxhighlight> |
|||
<syntaxhighlight lang="java"> |
|||
String decode(String string) { |
|||
Pattern pattern = Pattern.compile("%([A-Za-z\\d]{2})"); |
|||
Matcher matcher = pattern.matcher(string); |
|||
StringBuilder decoded = new StringBuilder(string); |
|||
char character; |
|||
int start, end, offset = 0; |
|||
while (matcher.find()) { |
|||
character = (char) Integer.parseInt(matcher.group(1), 16); |
|||
/* offset the matched index since were adjusting the string */ |
|||
start = matcher.start() - offset; |
|||
end = matcher.end() - offset; |
|||
decoded.replace(start, end, String.valueOf(character)); |
|||
offset += 2; |
|||
} |
|||
return decoded.toString(); |
|||
} |
|||
</syntaxhighlight> |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
|||
=={{header|JavaScript}}== |
|||
<syntaxhighlight lang="javascript">decodeURIComponent("http%3A%2F%2Ffoo%20bar%2F")</syntaxhighlight> |
|||
=={{header|jq}}== |
|||
{{works with|jq|1.4}} |
|||
If your jq already has "until", then the definition given below may be omitted. |
|||
<syntaxhighlight lang="jq"># Emit . and stop as soon as "condition" is true. |
|||
def until(condition; next): |
|||
def u: if condition then . else (next|u) end; |
|||
u; |
|||
def url_decode: |
|||
# The helper function converts the input string written in the given |
|||
# "base" to an integer |
|||
def to_i(base): |
|||
explode |
|||
| reverse |
|||
| map(if 65 <= . and . <= 90 then . + 32 else . end) # downcase |
|||
| map(if . > 96 then . - 87 else . - 48 end) # "a" ~ 97 => 10 ~ 87 |
|||
| reduce .[] as $c |
|||
# base: [power, ans] |
|||
([1,0]; (.[0] * base) as $b | [$b, .[1] + (.[0] * $c)]) | .[1]; |
|||
. as $in |
|||
| length as $length |
|||
| [0, ""] # i, answer |
|||
| until ( .[0] >= $length; |
|||
.[0] as $i |
|||
| if $in[$i:$i+1] == "%" |
|||
then [ $i + 3, .[1] + ([$in[$i+1:$i+3] | to_i(16)] | implode) ] |
|||
else [ $i + 1, .[1] + $in[$i:$i+1] ] |
|||
end) |
|||
| .[1]; # answer</syntaxhighlight> |
|||
'''Example''': |
|||
<syntaxhighlight lang="jq">"http%3A%2F%2Ffoo%20bar%2F" | url_decode</syntaxhighlight> |
|||
{{out}} |
|||
<syntaxhighlight lang="sh"> |
|||
"http://foo bar/"</syntaxhighlight> |
|||
=={{header|Julia}}== |
|||
<syntaxhighlight lang="julia"> |
|||
using URIParser |
|||
enc = "http%3A%2F%2Ffoo%20bar%2F" |
|||
dcd = unescape(enc) |
|||
println(enc, " => ", dcd) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http%3A%2F%2Ffoo%20bar%2F => http://foo bar/ |
|||
</pre> |
|||
=={{header|Kotlin}}== |
|||
<syntaxhighlight lang="scala">// version 1.1.2 |
|||
import java.net.URLDecoder |
|||
fun main(args: Array<String>) { |
|||
val encoded = arrayOf("http%3A%2F%2Ffoo%20bar%2F", "google.com/search?q=%60Abdu%27l-Bah%C3%A1") |
|||
for (e in encoded) println(URLDecoder.decode(e, "UTF-8")) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
|||
=={{header|Ksh}}== |
|||
<syntaxhighlight lang="ksh"> |
|||
url_decode() |
|||
{ |
|||
decode="${*//+/ }" |
|||
eval print -r -- "\$'${decode//'%'@(??)/'\'x\1"'\$'"}'" 2>/dev/null |
|||
} |
|||
url_decode "http%3A%2F%2Ffoo%20bar%2F" |
|||
url_decode "google.com/search?q=%60Abdu%27l-Bah%C3%A1" |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
|||
=={{header|Lambdatalk}}== |
|||
Currently lambdatalk has no builtin primitive for decoding URLs. Let's define it using Javascript. |
|||
<syntaxhighlight lang="scheme"> |
|||
1) define a new javascript primitive: |
|||
{script |
|||
LAMBDATALK.DICT['decodeURIComponent'] = function() { |
|||
return decodeURIComponent( arguments[0].trim() ); |
|||
}; |
|||
} |
|||
2) and use it: |
|||
{decodeURIComponent http%3A%2F%2Ffoo%20bar%2F} |
|||
-> http://foo bar/ |
|||
</syntaxhighlight> |
|||
=={{header|langur}}== |
|||
<syntaxhighlight lang="langur"> |
|||
val finish = fn s:b2s(map(fn x:number(x, 16), rest(split("%", s)))) |
|||
val decode = fn s:replace(s, re/(%[0-9A-Fa-f]{2})+/, finish) |
|||
writeln decode("http%3A%2F%2Ffoo%20bar%2F") |
|||
writeln decode("google.com/search?q=%60Abdu%27l-Bah%C3%A1") |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
|||
=={{header|Lasso}}== |
|||
<syntaxhighlight lang="lasso">bytes('http%3A%2F%2Ffoo%20bar%2F') -> decodeurl</syntaxhighlight> |
|||
-> http://foo bar/ |
|||
=={{header|Liberty BASIC}}== |
|||
<syntaxhighlight lang="lb"> |
|||
dim lookUp$( 256) |
|||
for i =0 to 256 |
|||
lookUp$( i) ="%" +dechex$( i) |
|||
next i |
|||
url$ ="http%3A%2F%2Ffoo%20bar%2F" |
|||
print "Supplied URL '"; url$; "'" |
|||
print "As string '"; url2string$( url$); "'" |
|||
end |
|||
function url2string$( i$) |
|||
for j =1 to len( i$) |
|||
c$ =mid$( i$, j, 1) |
|||
if c$ ="%" then |
|||
nc$ =chr$( hexdec( mid$( i$, j +1, 2))) |
|||
url2string$ =url2string$ +nc$ |
|||
j =j +2 |
|||
else |
|||
url2string$ =url2string$ +c$ |
|||
end if |
|||
next j |
|||
end function |
|||
</syntaxhighlight> |
|||
Supplied URL 'http%3A%2F%2Ffoo%20bar%2F' |
|||
As string 'http://foo bar/' |
|||
=={{header|Lingo}}== |
|||
<syntaxhighlight lang="lingo">---------------------------------------- |
|||
-- URL decodes a string |
|||
-- @param {string} str |
|||
-- @return {string} |
|||
---------------------------------------- |
|||
on urldecode (str) |
|||
res = "" |
|||
ba = bytearray() |
|||
len = str.length |
|||
repeat with i = 1 to len |
|||
c = str.char[i] |
|||
if (c = "%") then |
|||
-- fastest hex-to-dec conversion hack based on Lingo's rgb object |
|||
ba.writeInt8(rgb(str.char[i+1..i+2]).blue) |
|||
i = i + 2 |
|||
else if (c = "+") then |
|||
ba.writeInt8(32) |
|||
else |
|||
ba.writeInt8(chartonum(c)) |
|||
end if |
|||
end repeat |
|||
ba.position = 1 |
|||
return ba.readRawString(ba.length) |
|||
end</syntaxhighlight> |
|||
<syntaxhighlight lang="lingo">put urldecode("http%3A%2F%2Ffoo%20bar%2F") |
|||
put urldecode("google.com/search?q=%60Abdu%27l-Bah%C3%A1")</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
-- "http://foo bar/" |
|||
-- "google.com/search?q=`Abdu'l-Bahá" |
|||
</pre> |
|||
=={{header|LiveCode}}== |
|||
<syntaxhighlight lang="livecode">put urlDecode("http%3A%2F%2Ffoo%20bar%2F") & cr & \ |
|||
urlDecode("google.com/search?q=%60Abdu%27l-Bah%C3%A1")</syntaxhighlight>Results<syntaxhighlight lang="text">http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bah√°</syntaxhighlight> |
|||
=={{header|Lua}}== |
|||
<syntaxhighlight lang="lua">function decodeChar(hex) |
|||
return string.char(tonumber(hex,16)) |
|||
end |
|||
function decodeString(str) |
|||
local output, t = string.gsub(str,"%%(%x%x)",decodeChar) |
|||
return output |
|||
end |
|||
-- will print "http://foo bar/" |
|||
print(decodeString("http%3A%2F%2Ffoo%20bar%2F"))</syntaxhighlight> |
|||
=={{header|M2000 Interpreter}}== |
|||
Function Len(string) return length in words, so a value 1.5 means 3 bytes |
|||
We can add strings with half word at the end of a series of words. |
|||
A$=str$("A") has a length of 0.5 |
|||
b$=chr$(a$) revert bytes to words adding zeroes after each character |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
Module CheckIt { |
|||
Function decodeUrl$(a$) { |
|||
DIM a$() |
|||
a$()=Piece$(a$, "%") |
|||
if len(a$())=1 then =str$(a$):exit |
|||
k=each(a$(),2) |
|||
\\ convert to one byte per character using str$(string) |
|||
acc$=str$(a$(0)) |
|||
While k { |
|||
\\ chr$() convert to UTF16LE |
|||
\\ str$() convert to ANSI using locale (can be 1033 we can set it before as Locale 1033) |
|||
\\ so chr$(0x93) give 0x201C |
|||
\\ str$(chr$(0x93)) return one byte 93 in ANSI as string of one byte length |
|||
\\ numbers are for UTF-8 so we have to preserve them |
|||
acc$+=str$(Chr$(Eval("0x"+left$(a$(k^),2)))+Mid$(a$(k^),3)) |
|||
} |
|||
=acc$ |
|||
} |
|||
\\ decode from utf8 |
|||
final$=DecodeUrl$("google.com/search?q=%60Abdu%27l-Bah%C3%A1") |
|||
Print string$(final$ as utf8dec)="google.com/search?q=`Abdu'l-Bahá" |
|||
final$=DecodeUrl$("http%3A%2F%2Ffoo%20bar%2F") |
|||
Print string$(final$ as utf8dec)="http://foo bar/" |
|||
} |
|||
CheckIt |
|||
</syntaxhighlight> |
|||
=={{header|Maple}}== |
|||
<syntaxhighlight lang="maple">StringTools:-Decode("http%3A%2F%2Ffoo%20bar%2F", encoding=percent);</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> "http://foo bar/"</pre> |
|||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
|||
<syntaxhighlight lang="mathematica">URLDecoding[url_] := |
|||
StringReplace[url, "%" ~~ x_ ~~ y_ :> FromDigits[x ~~ y, 16]] //. |
|||
StringExpression[x___, Longest[n__Integer], y___] :> |
|||
StringExpression[x, FromCharacterCode[{n}, "UTF8"], y]</syntaxhighlight> |
|||
Example use: |
|||
<syntaxhighlight lang="mathematica">URLDecoding["http%3A%2F%2Ffoo%20bar%2F"]</syntaxhighlight> |
|||
{{out}} |
|||
<pre>http://foo bar/</pre> |
|||
---- |
|||
Using the built-in URLDecode (http://reference.wolfram.com/language/ref/URLDecode.html) function: |
|||
{{out}} |
|||
<pre> |
|||
In[]:= URLDecode["http%3A%2F%2Ffoo%20bar%2F"] |
|||
Out[]= "http://foo bar/" |
|||
In[]:= URLDecode["google.com/search?q=%60Abdu%27l-Bah%C3%A1"] |
|||
Out[]= "google.com/search?q=`Abdu'l-Bahá" |
|||
In[]:= URLDecode[{"Kurt+G%C3%B6del", "Paul+Erd%C5%91s"}] |
|||
Out[]= {"Kurt Gödel", "Paul Erdős"} |
|||
</pre> |
|||
=={{header|MATLAB}} / {{header|Octave}}== |
|||
<syntaxhighlight lang="matlab">function u = urldecoding(s) |
|||
u = ''; |
|||
k = 1; |
|||
while k<=length(s) |
|||
if s(k) == '%' && k+2 <= length(s) |
|||
u = sprintf('%s%c', u, char(hex2dec(s((k+1):(k+2))))); |
|||
k = k + 3; |
|||
else |
|||
u = sprintf('%s%c', u, s(k)); |
|||
k = k + 1; |
|||
end |
|||
end |
|||
end</syntaxhighlight> |
|||
Usage: |
|||
<pre>octave:3> urldecoding('http%3A%2F%2Ffoo%20bar%2F') |
|||
ans = http://foo bar/</pre> |
|||
=={{header|NetRexx}}== |
=={{header|NetRexx}}== |
||
< |
<syntaxhighlight lang="netrexx">/* NetRexx */ |
||
options replace format comments java crossref savelog symbols nobinary |
options replace format comments java crossref savelog symbols nobinary |
||
Line 125: | Line 1,172: | ||
return decoded |
return decoded |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
|||
'''Output:''' |
|||
<pre style="height: 20ex; overflow: scroll;"> |
<pre style="height: 20ex; overflow: scroll;"> |
||
http%3A%2F%2Ffoo%20bar%2F |
http%3A%2F%2Ffoo%20bar%2F |
||
Line 139: | Line 1,186: | ||
</pre> |
</pre> |
||
=={{header| |
=={{header|NewLISP}}== |
||
<syntaxhighlight lang="newlisp">;; universal decoder, works for ASCII and UTF-8 |
|||
<lang Perl>#!/usr/bin/perl -w |
|||
;; (source http://www.newlisp.org/index.cgi?page=Code_Snippets) |
|||
use strict ; |
|||
(define (url-decode url (opt nil)) |
|||
use URI::Escape ; |
|||
(if opt (replace "+" url " ")) |
|||
(replace "%([0-9a-f][0-9a-f])" url (pack "b" (int $1 0 16)) 1)) |
|||
(url-decode "http%3A%2F%2Ffoo%20bar%2F")</syntaxhighlight> |
|||
my $unencoded = uri_unescape( $encoded ) ; |
|||
print "The unencoded string is $unencoded !\n" ;</lang> |
|||
=={{header| |
=={{header|Nim}}== |
||
<syntaxhighlight lang="nim">import cgi |
|||
<lang Perl 6>use v6; |
|||
echo decodeUrl("http%3A%2F%2Ffoo%20bar%2F")</syntaxhighlight> |
|||
{{out}} |
|||
my regex url |
|||
<pre>http://foo bar/</pre> |
|||
{ |
|||
[ <text=&text> [\% <hex=&hex>]+ ]+ <text2=&text>? |
|||
} |
|||
=={{header|Oberon-2}}== |
|||
my regex hex |
|||
{{works with|oo2c}} |
|||
{ |
|||
<syntaxhighlight lang="oberon2"> |
|||
\w\w |
|||
MODULE URLDecoding; |
|||
} |
|||
IMPORT |
|||
URI := URI:String, |
|||
Out := NPCT:Console; |
|||
BEGIN |
|||
Out.String(URI.Unescape("http%3A%2F%2Ffoo%20bar%2F"));Out.Ln; |
|||
Out.String(URI.Unescape("google.com/search?q=%60Abdu%27l-Bah%C3%A1"));Out.Ln; |
|||
END URLDecoding. |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
|||
=={{header|Objeck}}== |
|||
my regex text |
|||
<syntaxhighlight lang="objeck"> |
|||
{ |
|||
class UrlDecode { |
|||
\w+ |
|||
function : Main(args : String[]) ~ Nil { |
|||
Net.UrlUtility->Decode("http%3A%2F%2Ffoo%20bar%2F")->PrintLine(); |
|||
} |
|||
} |
} |
||
</syntaxhighlight> |
|||
=={{header|Objective-C}}== |
|||
$url ~~ /<url=&url>/; |
|||
<syntaxhighlight lang="objc">NSString *encoded = @"http%3A%2F%2Ffoo%20bar%2F"; |
|||
NSString *normal = [encoded stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; |
|||
NSLog(@"%@", normal);</syntaxhighlight> |
|||
{{works with|Mac OS X|10.9+}}{{works with|iOS|7+}} |
|||
<syntaxhighlight lang="objc">NSString *encoded = @"http%3A%2F%2Ffoo%20bar%2F"; |
|||
NSString *normal = [encoded stringByRemovingPercentEncoding]; |
|||
NSLog(@"%@", normal);</syntaxhighlight> |
|||
=={{header|OCaml}}== |
|||
my $dec_url; |
|||
for $<url>.caps |
|||
Using the library [http://projects.camlcity.org/projects/ocamlnet.html ocamlnet] from the interactive loop: |
|||
{ |
|||
if .key eq "hex" |
|||
<syntaxhighlight lang="ocaml">$ ocaml |
|||
{ |
|||
# #use "topfind";; |
|||
$dec_url ~= :10("0x" ~ .value).chr; |
|||
# #require "netstring";; |
|||
} else { |
|||
$dec_url ~= .value; |
|||
# Netencoding.Url.decode "http%3A%2F%2Ffoo%20bar%2F" ;; |
|||
} |
|||
- : string = "http://foo bar/"</syntaxhighlight> |
|||
=={{header|ooRexx}}== |
|||
While the implementation shown for [[#REXX|Rexx]] will also work with ooRexx, this version uses ooRexx syntax to invoke the built-in functions. |
|||
<syntaxhighlight lang="oorexx">/* Rexx */ |
|||
X = 0 |
|||
url. = '' |
|||
X = X + 1; url.0 = X; url.X = 'http%3A%2F%2Ffoo%20bar%2F' |
|||
X = X + 1; url.0 = X; url.X = 'mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E' |
|||
X = X + 1; url.0 = X; url.X = '%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E' |
|||
Do u_ = 1 to url.0 |
|||
Say url.u_ |
|||
Say DecodeURL(url.u_) |
|||
Say |
|||
End u_ |
|||
Exit |
|||
DecodeURL: Procedure |
|||
Parse Arg encoded |
|||
decoded = '' |
|||
PCT = '%' |
|||
Do label e_ while encoded~length() > 0 |
|||
Parse Var encoded head (PCT) +1 code +2 tail |
|||
decoded = decoded || head |
|||
Select |
|||
when code~strip('T')~length() = 2 & code~datatype('X') then Do |
|||
code = code~x2c() |
|||
decoded = decoded || code |
|||
End |
|||
when code~strip('T')~length() \= 0 then Do |
|||
decoded = decoded || PCT |
|||
tail = code || tail |
|||
End |
|||
otherwise |
|||
Nop |
|||
End |
|||
encoded = tail |
|||
End e_ |
|||
Return decoded</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http%3A%2F%2Ffoo%20bar%2F |
|||
http://foo bar/ |
|||
mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E |
|||
mailto:"Ivan Aim" <ivan.aim@email.com> |
|||
%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E |
|||
mailto:"Irma User" <irma.user@mail.com> |
|||
</pre> |
|||
=={{header|PascalABC.NET}}== |
|||
<syntaxhighlight lang="delphi"> |
|||
uses System; |
|||
function URLDecode(s: string) := Uri.UnescapeDataString(s); |
|||
begin |
|||
Println(URLDecode('http%3A%2F%2Ffoo%20bar%2F')); |
|||
Println(URLDecode('google.com/search?q=%60Abdu%27l-Bah%C3%A1')); |
|||
Println(URLDecode('%25%32%35')); |
|||
end. |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
%25 |
|||
</pre> |
|||
=={{header|Perl}}== |
|||
<syntaxhighlight lang="perl">sub urldecode { |
|||
my $s = shift; |
|||
$s =~ tr/\+/ /; |
|||
$s =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/eg; |
|||
return $s; |
|||
} |
} |
||
print urldecode('http%3A%2F%2Ffoo+bar%2F')."\n"; |
|||
say $dec_url;</lang> |
|||
</syntaxhighlight> |
|||
<syntaxhighlight lang="perl">#!/usr/bin/perl -w |
|||
use strict ; |
|||
use URI::Escape ; |
|||
my $encoded = "http%3A%2F%2Ffoo%20bar%2F" ; |
|||
my $unencoded = uri_unescape( $encoded ) ; |
|||
print "The unencoded string is $unencoded !\n" ;</syntaxhighlight> |
|||
=={{header|Phix}}== |
|||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
-- demo\rosetta\decode_url.exw |
|||
-- =========================== |
|||
--</span> |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">decode_url</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">skip</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">skip</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">skip</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span> |
|||
<span style="color: #008080;">else</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'%'</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">scanres</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;"><=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">scanres</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">scanf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"#"</span><span style="color: #0000FF;">&</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"%x"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">scanres</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #008000;">"decode error"</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">skip</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span> |
|||
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">scanres</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'+'</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">' '</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">ch</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">decode_url</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"http%3A%2F%2Ffoo%20bar%2F"</span><span style="color: #0000FF;">)})</span> |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">decode_url</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"google.com/search?q=%60Abdu%27l-Bah%C3%A1"</span><span style="color: #0000FF;">)})</span> |
|||
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span> |
|||
<!--</syntaxhighlight>--> |
|||
{{Out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
|||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
< |
<syntaxhighlight lang="php"><?php |
||
$encoded = "http%3A%2F%2Ffoo%20bar%2F"; |
$encoded = "http%3A%2F%2Ffoo%20bar%2F"; |
||
$unencoded = rawurldecode($encoded); |
$unencoded = rawurldecode($encoded); |
||
echo "The unencoded string is $unencoded !\n"; |
echo "The unencoded string is $unencoded !\n"; |
||
?></ |
?></syntaxhighlight> |
||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
<pre>: (ht:Pack (chop "http%3A%2F%2Ffoo%20bar%2F")) |
<pre>: (ht:Pack (chop "http%3A%2F%2Ffoo%20bar%2F") T) |
||
-> "http://foo bar/"</pre> |
-> "http://foo bar/"</pre> |
||
=={{header|Pike}}== |
|||
<syntaxhighlight lang="pike"> |
|||
void main() |
|||
{ |
|||
array encoded_urls = ({ |
|||
"http%3A%2F%2Ffoo%20bar%2F", |
|||
"google.com/search?q=%60Abdu%27l-Bah%C3%A1" |
|||
}); |
|||
foreach(encoded_urls, string url) { |
|||
string decoded = Protocols.HTTP.uri_decode( url ); |
|||
write( string_to_utf8(decoded) +"\n" ); // Assume sink does UTF8 |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
|||
=={{header|PowerShell}}== |
|||
<syntaxhighlight lang="powershell"> |
|||
[System.Web.HttpUtility]::UrlDecode("http%3A%2F%2Ffoo%20bar%2F") |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
</pre> |
|||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<syntaxhighlight lang="purebasic">URL$ = URLDecoder("http%3A%2F%2Ffoo%20bar%2F") |
||
Debug URL$ ; http://foo bar/</ |
Debug URL$ ; http://foo bar/</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
<syntaxhighlight lang="python"> |
|||
<lang Python>import urllib |
|||
#Python 2.X |
|||
print urllib.unquote("http%3A%2F%2Ffoo%20bar%2F")</lang> |
|||
import urllib |
|||
print urllib.unquote("http%3A%2F%2Ffoo%20bar%2F") |
|||
#Python 3.5+ |
|||
from urllib.parse import unquote |
|||
print(unquote('http%3A%2F%2Ffoo%20bar%2F')) |
|||
</syntaxhighlight> |
|||
=={{header|R}}== |
|||
<syntaxhighlight lang="r">URLdecode("http%3A%2F%2Ffoo%20bar%2F")</syntaxhighlight> |
|||
=={{header|Racket}}== |
|||
<syntaxhighlight lang="racket"> |
|||
#lang racket |
|||
(require net/uri-codec) |
|||
(uri-decode "http%3A%2F%2Ffoo%20bar%2F") |
|||
</syntaxhighlight> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
<syntaxhighlight lang="raku" line>my @urls = < http%3A%2F%2Ffoo%20bar%2F |
|||
google.com/search?q=%60Abdu%27l-Bah%C3%A1 >; |
|||
say .subst( :g, |
|||
/ [ '%' ( <xdigit> ** 2 ) ]+ / , |
|||
{ Blob.new((:16(~$_) for $0)).decode } |
|||
) for @urls;</syntaxhighlight> |
|||
{{out}} |
|||
<pre>http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá</pre> |
|||
=={{header|Red}}== |
|||
<syntaxhighlight lang="rebol">>> dehex "http%3A%2F%2Ffoo%20bar%2F" |
|||
== "http://foo bar/" |
|||
>> dehex "google.com/search?q=%60Abdu%27l-Bah%C3%A1" |
|||
== "google.com/search?q=`Abdu'l-Bahá"</syntaxhighlight> |
|||
=={{header|Retro}}== |
=={{header|Retro}}== |
||
This is provided by the '''casket''' library (used for web app development). |
This is provided by the '''casket''' library (used for web app development). |
||
< |
<syntaxhighlight lang="retro">create buffer 32000 allot |
||
{{ |
{{ |
||
Line 221: | Line 1,497: | ||
}} |
}} |
||
"http%3A%2F%2Ffoo%20bar%2F" decode buffer puts</ |
"http%3A%2F%2Ffoo%20bar%2F" decode buffer puts</syntaxhighlight> |
||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
===version 1=== |
|||
<lang REXX>/* Rexx */ |
|||
{{Trans|ooRexx}} |
|||
Tested with the ooRexx and Regina interpreters. |
|||
<syntaxhighlight lang="rexx">/* Rexx */ |
|||
Do |
Do |
||
Line 250: | Line 1,529: | ||
PCT = '%' |
PCT = '%' |
||
Do |
Do while length(encoded) > 0 |
||
Parse Var encoded head (PCT) +1 code +2 tail |
Parse Var encoded head (PCT) +1 code +2 tail |
||
decoded = decoded || head |
decoded = decoded || head |
||
Select |
Select |
||
When length(strip(code, 'T')) = 2 & datatype(code, 'X') then Do |
|||
code = |
code = x2c(code) |
||
decoded = decoded || code |
decoded = decoded || code |
||
End |
End |
||
When length(strip(code, 'T')) \= 0 then Do |
|||
decoded = decoded || PCT |
decoded = decoded || PCT |
||
tail = code || tail |
tail = code || tail |
||
End |
End |
||
Otherwise Do |
|||
Nop |
Nop |
||
End |
End |
||
End |
End |
||
encoded = tail |
encoded = tail |
||
End |
End |
||
Return decoded |
Return decoded |
||
End |
End |
||
Exit |
Exit |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
|||
'''Output:''' |
|||
<pre> |
|||
<pre style="height: 20ex; overflow: scroll;"> |
|||
http%3A%2F%2Ffoo%20bar%2F |
http%3A%2F%2Ffoo%20bar%2F |
||
http://foo bar/ |
http://foo bar/ |
||
Line 284: | Line 1,563: | ||
%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E |
%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E |
||
mailto:"Irma User" <irma.user@mail.com> |
mailto:"Irma User" <irma.user@mail.com> |
||
</pre> |
|||
===version 2=== |
|||
This REXX version is identical to version 1, but with superfluous and dead code removed. |
|||
<syntaxhighlight lang="rexx">/*REXX program converts a URL─encoded string ──► its original unencoded form. */ |
|||
url.1='http%3A%2F%2Ffoo%20bar%2F' |
|||
url.2='mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E' |
|||
url.3='%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E' |
|||
URLs =3 |
|||
do j=1 for URLs |
|||
say url.j |
|||
say decodeURL(url.j) |
|||
say |
|||
end /*j*/ |
|||
exit |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
decodeURL: procedure; parse arg encoded; decoded= '' |
|||
do while encoded\=='' |
|||
parse var encoded head '%' +1 code +2 tail |
|||
decoded= decoded || head |
|||
L= length( strip( code, 'T') ) |
|||
select |
|||
when L==2 & datatype(code, "X") then decoded= decoded || x2c(code) |
|||
when L\==0 then do; decoded= decoded'%' |
|||
tail= code || tail |
|||
end |
|||
otherwise nop |
|||
end /*select*/ |
|||
encoded= tail |
|||
end /*while*/ |
|||
return decoded</syntaxhighlight> |
|||
{{out|output|text= is identical to the 1<sup>st</sup> REXX version.}} |
|||
===version 3=== |
|||
This REXX version is a shorter version of version 2. |
|||
<syntaxhighlight lang="rexx">/*REXX program converts & displays a URL─encoded string ──► its original unencoded form.*/ |
|||
url. = |
|||
url.1='http%3A%2F%2Ffoo%20bar%2F' |
|||
url.2='mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E' |
|||
url.3='%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E' |
|||
do j=1 until url.j==''; say /*process each URL; display blank line.*/ |
|||
say url.j /*display the original URL. */ |
|||
say URLdecode(url.j) /* " " decoded " */ |
|||
end /*j*/ |
|||
exit /*stick a fork in it, we're all done. */ |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
URLdecode: procedure; parse arg yyy /*get encoded URL from argument list. */ |
|||
yyy= translate(yyy, , '+') /*a special case for an encoded blank. */ |
|||
URL= |
|||
do until yyy=='' |
|||
parse var yyy plain '%' +1 code +2 yyy |
|||
URL= URL || plain |
|||
if datatype(code, 'X') then URL= URL || x2c(code) |
|||
else URL= URL'%'code |
|||
end /*until*/ |
|||
return URL</syntaxhighlight> |
|||
{{out|output|text= is identical to the 1<sup>st</sup> REXX version.}} |
|||
=={{header|Ruby}}== |
|||
Use any one of <code>CGI.unescape</code> or <code>URI.decode_www_form_component</code>. These methods also convert "+" to " ". |
|||
<syntaxhighlight lang="ruby">require 'cgi' |
|||
puts CGI.unescape("http%3A%2F%2Ffoo%20bar%2F") |
|||
# => "http://foo bar/"</syntaxhighlight> |
|||
{{works with|Ruby|1.9.2}} |
|||
<syntaxhighlight lang="ruby">require 'uri' |
|||
puts URI.decode_www_form_component("http%3A%2F%2Ffoo%20bar%2F") |
|||
# => "http://foo bar/"</syntaxhighlight> |
|||
<code>URI.unescape</code> (alias <code>URI.unencode</code>) still works. <code>URI.unescape</code> is obsolete since Ruby 1.9.2 because of problems with its sibling <code>URI.escape</code>. |
|||
=={{header|Rust}}== |
|||
<syntaxhighlight lang="rust">const INPUT1: &str = "http%3A%2F%2Ffoo%20bar%2F"; |
|||
const INPUT2: &str = "google.com/search?q=%60Abdu%27l-Bah%C3%A1"; |
|||
fn append_frag(text: &mut String, frag: &mut String) { |
|||
if !frag.is_empty() { |
|||
let encoded = frag.chars() |
|||
.collect::<Vec<char>>() |
|||
.chunks(2) |
|||
.map(|ch| { |
|||
u8::from_str_radix(&ch.iter().collect::<String>(), 16).unwrap() |
|||
}).collect::<Vec<u8>>(); |
|||
text.push_str(&std::str::from_utf8(&encoded).unwrap()); |
|||
frag.clear(); |
|||
} |
|||
} |
|||
fn decode(text: &str) -> String { |
|||
let mut output = String::new(); |
|||
let mut encoded_ch = String::new(); |
|||
let mut iter = text.chars(); |
|||
while let Some(ch) = iter.next() { |
|||
if ch == '%' { |
|||
encoded_ch.push_str(&format!("{}{}", iter.next().unwrap(), iter.next().unwrap())); |
|||
} else { |
|||
append_frag(&mut output, &mut encoded_ch); |
|||
output.push(ch); |
|||
} |
|||
} |
|||
append_frag(&mut output, &mut encoded_ch); |
|||
output |
|||
} |
|||
fn main() { |
|||
println!("{}", decode(INPUT1)); |
|||
println!("{}", decode(INPUT2)); |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
</pre> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
< |
{{libheader|Scala}}<syntaxhighlight lang="scala">import java.net.{URLDecoder, URLEncoder} |
||
import scala.compat.Platform.currentTime |
|||
val encoded="http%3A%2F%2Ffoo%20bar%2F" |
|||
val decoded=URLDecoder.decode(encoded, "UTF-8") |
|||
object UrlCoded extends App { |
|||
println(decoded) // -> http://foo bar/</lang> |
|||
val original = """http://foo bar/""" |
|||
val encoded: String = URLEncoder.encode(original, "UTF-8") |
|||
assert(encoded == "http%3A%2F%2Ffoo+bar%2F", s"Original: $original not properly encoded: $encoded") |
|||
val percentEncoding = encoded.replace("+", "%20") |
|||
assert(percentEncoding == "http%3A%2F%2Ffoo%20bar%2F", s"Original: $original not properly percent-encoded: $percentEncoding") |
|||
assert(URLDecoder.decode(encoded, "UTF-8") == URLDecoder.decode(percentEncoding, "UTF-8")) |
|||
println(s"Successfully completed without errors. [total ${currentTime - executionStart} ms]") |
|||
}</syntaxhighlight> |
|||
=={{header|Seed7}}== |
|||
The library [http://seed7.sourceforge.net/libraries/encoding.htm encoding.s7i] defines functions |
|||
to handle URL respectively percent encoding. |
|||
The function [http://seed7.sourceforge.net/libraries/encoding.htm#fromPercentEncoded%28in_string%29 fromPercentEncoded] |
|||
decodes a percend-encoded string. |
|||
The function [http://seed7.sourceforge.net/libraries/encoding.htm#fromUrlEncoded%28in_string%29 fromUrlEncoded] |
|||
works like ''fromPercentEncoded'' and additionally decodes '+' with a space. |
|||
Both functions return byte sequences. |
|||
To decode Unicode characters it is necessary to convert them from UTF-8 with [https://seed7.sourceforge.net/libraries/unicode.htm#fromUtf8(in_string) fromUtf8] afterwards. |
|||
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i"; |
|||
include "encoding.s7i"; |
|||
const proc: main is func |
|||
begin |
|||
writeln(fromPercentEncoded("http%3A%2F%2Ffoo%20bar%2F")); |
|||
writeln(fromUrlEncoded("http%3A%2F%2Ffoo+bar%2F")); |
|||
end func;</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
http://foo bar/ |
|||
</pre> |
|||
=={{header|Sidef}}== |
|||
{{trans|Perl}} |
|||
<syntaxhighlight lang="ruby">func urldecode(str) { |
|||
str.gsub!('+', ' '); |
|||
str.gsub!(/\%([A-Fa-f0-9]{2})/, {|a| 'C'.pack(a.hex)}); |
|||
return str; |
|||
} |
|||
say urldecode('http%3A%2F%2Ffoo+bar%2F'); # => "http://foo bar/"</syntaxhighlight> |
|||
=={{header|Swift}}== |
|||
<syntaxhighlight lang="swift">import Foundation |
|||
let encoded = "http%3A%2F%2Ffoo%20bar%2F" |
|||
if let normal = encoded.stringByReplacingPercentEscapesUsingEncoding(NSUTF8StringEncoding) { |
|||
println(normal) |
|||
}</syntaxhighlight> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
This code is careful to ensure that any untoward metacharacters in the input string still do not cause any problems. |
This code is careful to ensure that any untoward metacharacters in the input string still do not cause any problems. |
||
< |
<syntaxhighlight lang="tcl">proc urlDecode {str} { |
||
set specialMap {"[" "%5B" "]" "%5D"} |
set specialMap {"[" "%5B" "]" "%5D"} |
||
set seqRE {%([0-9a-fA-F]{2})} |
set seqRE {%([0-9a-fA-F]{2})} |
||
Line 300: | Line 1,749: | ||
set modStr [regsub -all $seqRE [string map $specialMap $str] $replacement] |
set modStr [regsub -all $seqRE [string map $specialMap $str] $replacement] |
||
return [encoding convertfrom utf-8 [subst -nobackslash -novariable $modStr]] |
return [encoding convertfrom utf-8 [subst -nobackslash -novariable $modStr]] |
||
}</ |
}</syntaxhighlight> |
||
Demonstrating: |
Demonstrating: |
||
< |
<syntaxhighlight lang="tcl">puts [urlDecode "http%3A%2F%2Ffoo%20bar%2F"]</syntaxhighlight> |
||
{{out}} |
|||
Output: |
|||
<pre>http://foo bar/</pre> |
<pre>http://foo bar/</pre> |
||
=={{header|TUSCRIPT}}== |
=={{header|TUSCRIPT}}== |
||
< |
<syntaxhighlight lang="tuscript"> |
||
$$ MODE TUSCRIPT |
$$ MODE TUSCRIPT |
||
url_encoded="http%3A%2F%2Ffoo%20bar%2F" |
url_encoded="http%3A%2F%2Ffoo%20bar%2F" |
||
Line 315: | Line 1,765: | ||
PRINT "encoded: ", url_encoded |
PRINT "encoded: ", url_encoded |
||
PRINT "decoded: ", url_decoded |
PRINT "decoded: ", url_decoded |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
encoded: http%3A%2F%2Ffoo%20bar%2F |
encoded: http%3A%2F%2Ffoo%20bar%2F |
||
decoded: http://foo bar/ |
decoded: http://foo bar/ |
||
</pre> |
</pre> |
||
=={{header|UNIX Shell}}== |
|||
{{works with|bash}} |
|||
{{works with|ksh}} |
|||
<syntaxhighlight lang="bash">urldecode() { local u="${1//+/ }"; printf '%b' "${u//%/\\x}"; }</syntaxhighlight> |
|||
Alternative: Replace <code>printf '%b' "${u//%/\\x}"</code> with <code>echo -e "${u//%/\\x}"</code> |
|||
Example: |
|||
<syntaxhighlight lang="bash">urldecode http%3A%2F%2Ffoo%20bar%2F |
|||
http://foo bar/ |
|||
urldecode google.com/search?q=%60Abdu%27l-Bah%C3%A1 |
|||
google.com/search?q=`Abdu'l-Bahároot@ |
|||
</syntaxhighlight> |
|||
<syntaxhighlight lang="bash">function urldecode |
|||
{ |
|||
typeset encoded=$1 decoded= rest= c= c1= c2= |
|||
typeset rest2= bug='rest2=${rest}' |
|||
if [[ -z ${BASH_VERSION:-} ]]; then |
|||
typeset -i16 hex=0; typeset -i8 oct=0 |
|||
# bug /usr/bin/sh HP-UX 11.00 |
|||
typeset _encoded='xyz%26xyz' |
|||
rest="${_encoded#?}" |
|||
c="${_encoded%%${rest}}" |
|||
if (( ${#c} != 1 )); then |
|||
typeset qm='????????????????????????????????????????????????????????????????????????' |
|||
typeset bug='(( ${#rest} > 0 )) && typeset -L${#rest} rest2="${qm}" || rest2=${rest}' |
|||
fi |
|||
fi |
|||
rest="${encoded#?}" |
|||
eval ${bug} |
|||
c="${encoded%%${rest2}}" |
|||
encoded="${rest}" |
|||
while [[ -n ${c} ]]; do |
|||
if [[ ${c} = '%' ]]; then |
|||
rest="${encoded#?}" |
|||
eval ${bug} |
|||
c1="${encoded%%${rest2}}" |
|||
encoded="${rest}" |
|||
rest="${encoded#?}" |
|||
eval ${bug} |
|||
c2="${encoded%%${rest2}}" |
|||
encoded="${rest}" |
|||
if [[ -z ${c1} || -z ${c2} ]]; then |
|||
c="%${c1}${c2}" |
|||
echo "WARNING: invalid % encoding: ${c}" >&2 |
|||
elif [[ -n ${BASH_VERSION:-} ]]; then |
|||
c="\\x${c1}${c2}" |
|||
c=$(\echo -e "${c}") |
|||
else |
|||
hex="16#${c1}${c2}"; oct=hex |
|||
c="\\0${oct#8\#}" |
|||
c=$(print -- "${c}") |
|||
fi |
|||
elif [[ ${c} = '+' ]]; then |
|||
c=' ' |
|||
fi |
|||
decoded="${decoded}${c}" |
|||
rest="${encoded#?}" |
|||
eval ${bug} |
|||
c="${encoded%%${rest2}}" |
|||
encoded="${rest}" |
|||
done |
|||
if [[ -n ${BASH_VERSION:-} ]]; then |
|||
\echo -E "${decoded}" |
|||
else |
|||
print -r -- "${decoded}" |
|||
fi |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|VBScript}}== |
|||
<syntaxhighlight lang="vbscript">Function RegExTest(str,patrn) |
|||
Dim regEx |
|||
Set regEx = New RegExp |
|||
regEx.IgnoreCase = True |
|||
regEx.Pattern = patrn |
|||
RegExTest = regEx.Test(str) |
|||
End Function |
|||
Function URLDecode(sStr) |
|||
Dim str,code,a0 |
|||
str="" |
|||
code=sStr |
|||
code=Replace(code,"+"," ") |
|||
While len(code)>0 |
|||
If InStr(code,"%")>0 Then |
|||
str = str & Mid(code,1,InStr(code,"%")-1) |
|||
code = Mid(code,InStr(code,"%")) |
|||
a0 = UCase(Mid(code,2,1)) |
|||
If a0="U" And RegExTest(code,"^%u[0-9A-F]{4}") Then |
|||
str = str & ChrW((Int("&H" & Mid(code,3,4)))) |
|||
code = Mid(code,7) |
|||
ElseIf a0="E" And RegExTest(code,"^(%[0-9A-F]{2}){3}") Then |
|||
str = str & ChrW((Int("&H" & Mid(code,2,2)) And 15) * 4096 + (Int("&H" & Mid(code,5,2)) And 63) * 64 + (Int("&H" & Mid(code,8,2)) And 63)) |
|||
code = Mid(code,10) |
|||
ElseIf a0>="C" And a0<="D" And RegExTest(code,"^(%[0-9A-F]{2}){2}") Then |
|||
str = str & ChrW((Int("&H" & Mid(code,2,2)) And 3) * 64 + (Int("&H" & Mid(code,5,2)) And 63)) |
|||
code = Mid(code,7) |
|||
ElseIf (a0<="B" Or a0="F") And RegExTest(code,"^%[0-9A-F]{2}") Then |
|||
str = str & Chr(Int("&H" & Mid(code,2,2))) |
|||
code = Mid(code,4) |
|||
Else |
|||
str = str & "%" |
|||
code = Mid(code,2) |
|||
End If |
|||
Else |
|||
str = str & code |
|||
code = "" |
|||
End If |
|||
Wend |
|||
URLDecode = str |
|||
End Function |
|||
url = "http%3A%2F%2Ffoo%20bar%C3%A8%2F" |
|||
WScript.Echo "Encoded URL: " & url & vbCrLf &_ |
|||
"Decoded URL: " & UrlDecode(url)</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Encoded URL: http%3A%2F%2Ffoo%20bar%C3%A8%2F |
|||
Decoded URL: http://foo barè/</pre> |
|||
=={{header|V (Vlang)}}== |
|||
<syntaxhighlight lang="v (vlang)">import net.urllib |
|||
fn main() { |
|||
for escaped in [ |
|||
"http%3A%2F%2Ffoo%20bar%2F", |
|||
"google.com/search?q=%60Abdu%27l-Bah%C3%A1", |
|||
] { |
|||
u := urllib.query_unescape(escaped)? |
|||
println(u) |
|||
} |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
|||
=={{header|Wren}}== |
|||
{{libheader|Wren-fmt}} |
|||
<syntaxhighlight lang="wren">import "./fmt" for Conv |
|||
var urlDecode = Fn.new { |enc| |
|||
var res = "" |
|||
var i = 0 |
|||
while (i < enc.count) { |
|||
var c = enc[i] |
|||
if (c == "\%") { |
|||
var b = Conv.atoi(enc[i+1..i+2], 16) |
|||
res = res + String.fromByte(b) |
|||
i = i + 3 |
|||
} else { |
|||
res = res + c |
|||
i = i + 1 |
|||
} |
|||
} |
|||
return res |
|||
} |
|||
// We need to escape % characters in Wren as % is otherwise used for string interpolation. |
|||
var encs = [ |
|||
"http\%3A\%2F\%2Ffoo\%20bar\%2F", |
|||
"google.com/search?q=\%60Abdu\%27l-Bah\%C3\%A1" |
|||
] |
|||
for (enc in encs)System.print(urlDecode.call(enc))</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
google.com/search?q=`Abdu'l-Bahá |
|||
</pre> |
|||
=={{header|XPL0}}== |
|||
<syntaxhighlight lang="xpl0">code Text=12; |
|||
string 0; \use zero-terminated strings |
|||
func Decode(S0); \Decode URL string and return its address |
|||
char S0; |
|||
char S1(80); \BEWARE: very temporary string space returned |
|||
int C, N, I, J; |
|||
[I:= 0; J:= 0; |
|||
repeat C:= S0(I); I:= I+1; \get char |
|||
if C=^% then \convert hex to char |
|||
[C:= S0(I); I:= I+1; |
|||
if C>=^a then C:= C & ~$20; \convert to uppercase |
|||
N:= C - (if C<=^9 then ^0 else ^A-10); |
|||
C:= S0(I); I:= I+1; |
|||
if C>=^a then C:= C & ~$20; |
|||
C:= N*16 + C - (if C<=^9 then ^0 else ^A-10); |
|||
]; |
|||
S1(J):= C; J:= J+1; \put char in output string |
|||
until C=0; |
|||
return S1; |
|||
]; |
|||
Text(0, Decode("http%3A%2F%2Ffoo%20bar%2f"))</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
http://foo bar/ |
|||
</pre> |
|||
=={{header|Yabasic}}== |
|||
{{trans|Phix}} |
|||
<syntaxhighlight lang="yabasic">sub decode_url$(s$) |
|||
local res$, ch$ |
|||
while(s$ <> "") |
|||
ch$ = left$(s$, 1) |
|||
if ch$ = "%" then |
|||
ch$ = chr$(dec(mid$(s$, 2, 2))) |
|||
s$ = right$(s$, len(s$) - 3) |
|||
else |
|||
if ch$ = "+" ch$ = " " |
|||
s$ = right$(s$, len(s$) - 1) |
|||
endif |
|||
res$ = res$ + ch$ |
|||
wend |
|||
return res$ |
|||
end sub |
|||
print decode_url$("http%3A%2F%2Ffoo%20bar%2F") |
|||
print decode_url$("google.com/search?q=%60Abdu%27l-Bah%C3%A1")</syntaxhighlight> |
|||
=={{header|zkl}}== |
|||
<syntaxhighlight lang="zkl">"http%3A%2F%2Ffoo%20bar%2F".pump(String, // push each char through these fcns: |
|||
fcn(c){ if(c=="%") return(Void.Read,2); return(Void.Skip,c) },// %-->read 2 chars else pass through |
|||
fcn(_,b,c){ (b+c).toInt(16).toChar() }) // "%" (ignored) "3"+"1"-->0x31-->"1"</syntaxhighlight> |
|||
{{out}} |
|||
<pre>http://foo bar/</pre> |
|||
or use libCurl: |
|||
<syntaxhighlight lang="zkl">var Curl=Import.lib("zklCurl"); |
|||
Curl.urlDecode("http%3A%2F%2Ffoo%20bar%2F");</syntaxhighlight> |
|||
{{out}}<pre>http://foo bar/</pre> |
Latest revision as of 21:36, 14 June 2024
You are encouraged to solve this task according to the task description, using any language you may know.
This task (the reverse of URL encoding and distinct from URL parser) is to provide a function or mechanism to convert an URL-encoded string into its original unencoded form.
- Test cases
- The encoded string "
http%3A%2F%2Ffoo%20bar%2F
" should be reverted to the unencoded form "http://foo bar/
".
- The encoded string "
google.com/search?q=%60Abdu%27l-Bah%C3%A1
" should revert to the unencoded form "google.com/search?q=`Abdu'l-Bahá
".
- The encoded string "
%25%32%35
" should revert to the unencoded form "%25
" and not "%
".
11l
F url_decode(s)
V r = ‘’
V i = 0
L i < s.len
I s[i] == ‘%’
[Byte] b
L i < s.len & s[i] == ‘%’
i++
b.append(Int(s[i.+2], radix' 16))
i += 2
r ‘’= b.decode(‘utf-8’)
E
r ‘’= s[i]
i++
R r
print(url_decode(‘http%3A%2F%2Ffoo%20bar%2F’))
print(url_decode(‘https://ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%B0%D0%BD%D1%81%D0%BF%D0%B0%D0%B9%D0%BB%D0%B5%D1%80’))
- Output:
http://foo bar/ https://ru.wikipedia.org/wiki/Транспайлер
ABAP
REPORT Z_DECODE_URL.
DATA: lv_encoded_url TYPE string VALUE 'http%3A%2F%2Ffoo%20bar%2F',
lv_decoded_url TYPE string.
CALL METHOD CL_HTTP_UTILITY=>UNESCAPE_URL
EXPORTING
ESCAPED = lv_encoded_url
RECEIVING
UNESCAPED = lv_decoded_url.
WRITE: 'Encoded URL: ', lv_encoded_url, /, 'Decoded URL: ', lv_decoded_url.
Action!
PROC Append(CHAR ARRAY s CHAR c)
s(0)==+1
s(s(0))=c
RETURN
CHAR FUNC GetCharFromHex(CHAR c1,c2)
CHAR ARRAY hex=['0 '1 '2 '3 '4 '5 '6 '7 '8 '9 'A 'B 'C 'D 'E 'F]
BYTE i,res
res=0
FOR i=0 TO 15
DO
IF c1=hex(i) THEN res==+i LSH 4 FI
IF c2=hex(i) THEN res==+i FI
OD
RETURN (res)
PROC Decode(CHAR ARRAY in,out)
BYTE i
CHAR c
out(0)=0
i=1
WHILE i<=in(0)
DO
c=in(i)
i==+1
IF c='+ THEN
Append(out,' )
ELSEIF c='% THEN
c=GetCharFromHex(in(i),in(i+1))
i==+2
Append(out,c)
ELSE
Append(out,c)
FI
OD
RETURN
PROC PrintInv(CHAR ARRAY a)
BYTE i
IF a(0)>0 THEN
FOR i=1 TO a(0)
DO
Put(a(i)%$80)
OD
FI
RETURN
PROC Test(CHAR ARRAY in)
CHAR ARRAY out(256)
PrintInv("input ")
PrintF(" %S%E",in)
Decode(in,out)
PrintInv("decoded")
PrintF(" %S%E%E",out)
RETURN
PROC Main()
Test("http%3A%2F%2Ffoo%20bar%2F")
Test("http%3A%2F%2Ffoo+bar%2F*_-.html")
RETURN
- Output:
Screenshot from Atari 8-bit computer
input http%3A%2F%2Ffoo%20bar%2F decoded http://foo bar/ input http%3A%2F%2Ffoo+bar%2F*_-.html decoded http://foo bar/*_-.html
Ada
with AWS.URL;
with Ada.Text_IO; use Ada.Text_IO;
procedure Decode is
Encoded : constant String := "http%3A%2F%2Ffoo%20bar%2F";
begin
Put_Line (AWS.URL.Decode (Encoded));
end Decode;
Without external libraries:
package URL is
function Decode (URL : in String) return String;
end URL;
package body URL is
function Decode (URL : in String) return String is
Buffer : String (1 .. URL'Length);
Filled : Natural := 0;
Position : Positive := URL'First;
begin
while Position in URL'Range loop
Filled := Filled + 1;
case URL (Position) is
when '+' =>
Buffer (Filled) := ' ';
Position := Position + 1;
when '%' =>
Buffer (Filled) :=
Character'Val
(Natural'Value
("16#" & URL (Position + 1 .. Position + 2) & "#"));
Position := Position + 3;
when others =>
Buffer (Filled) := URL (Position);
Position := Position + 1;
end case;
end loop;
return Buffer (1 .. Filled);
end Decode;
end URL;
with Ada.Command_Line,
Ada.Text_IO;
with URL;
procedure Test_URL_Decode is
use Ada.Command_Line, Ada.Text_IO;
begin
if Argument_Count = 0 then
Put_Line (URL.Decode ("http%3A%2F%2Ffoo%20bar%2F"));
else
for I in 1 .. Argument_Count loop
Put_Line (URL.Decode (Argument (I)));
end loop;
end if;
end Test_URL_Decode;
ALGOL 68
Note: See the discussion page re displaying the results (which is mostly focused on the AWK solution but will apply elsewhere too).
For the second task example, this outputs the encoded UTF-8 characters, what you see depends on what you look at it with...
# returns c decoded as a hex digit #
PROC hex value = ( CHAR c )INT: IF c >= "0" AND c <= "9" THEN ABS c - ABS "0"
ELIF c >= "A" AND c <= "F" THEN 10 + ( ABS c - ABS "A" )
ELSE 10 + ( ABS c - ABS "a" )
FI;
# returns the URL encoded string decoded - minimal error handling #
PROC url decode = ( STRING encoded )STRING:
BEGIN
[ LWB encoded : UPB encoded ]CHAR result;
INT result pos := LWB encoded;
INT pos := LWB encoded;
INT max pos := UPB encoded;
INT max encoded := max pos - 3;
WHILE pos <= UPB encoded
DO
IF encoded[ pos ] /= "%" AND pos <= max encoded
THEN
# not a coded character #
result[ result pos ] := encoded[ pos ];
pos +:= 1
ELSE
# have an encoded character #
result[ result pos ] := REPR ( ( 16 * hex value( encoded[ pos + 1 ] ) )
+ hex value( encoded[ pos + 2 ] )
);
pos +:= 3
FI;
result pos +:= 1
OD;
result[ LWB result : result pos - 1 ]
END # url decode # ;
# test the url decode procedure #
print( ( url decode( "http%3A%2F%2Ffoo%20bar%2F" ), newline ) );
print( ( url decode( "google.com/search?q=%60Abdu%27l-Bah%C3%A1" ), newline ) )
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
Apex
EncodingUtil.urlDecode('http%3A%2F%2Ffoo%20bar%2F', 'UTF-8');
EncodingUtil.urlDecode('google.com/search?q=%60Abdu%27l-Bah%C3%A1', 'UTF-8');
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
AppleScript
AST URL decode "google.com/search?q=%60Abdu%27l-Bah%C3%A1"
Arturo
print decode.url "http%3A%2F%2Ffoo%20bar%2F"
print decode.url "google.com/search?q=%60Abdu%27l-Bah%C3%A1"
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
AutoHotkey
UriDecode(Uri) {
LoopOffset := 0
VarLength := 0
VarSetCapacity(Var, StrPut(Uri, "UTF-8"), 0)
Loop Parse, Uri
{
If (A_Index < LoopOffset) {
Continue
}
If (A_LoopField = Chr(37)) {
Number := "0x" . SubStr(Uri, A_Index + 1, 2)
LoopOffset := A_Index + 3
}
Else {
Number := Ord(A_LoopField)
}
NumPut(Number, Var, VarLength++, "UChar")
}
Return StrGet(&Var, VarLength, "UTF-8")
}
MsgBox % UriDecode("http%3A%2F%2Ffoo%20bar%2F")
MsgBox % UriDecode("google.com/search?q=%60Abdu%27l-Bah%C3%A1")
MsgBox % UriDecode("%25%32%35")
AWK
# syntax:
awk '
BEGIN {
str = "http%3A%2F%2Ffoo%20bar%2F" # "http://foo bar/"
printf("%s\n",str)
len=length(str)
for (i=1;i<=len;i++) {
if ( substr(str,i,1) == "%") {
L = substr(str,1,i-1) # chars to left of "%"
M = substr(str,i+1,2) # 2 chars to right of "%"
R = substr(str,i+3) # chars to right of "%xx"
str = sprintf("%s%c%s",L,hex2dec(M),R)
}
}
printf("%s\n",str)
exit(0)
}
function hex2dec(s, num) {
num = index("0123456789ABCDEF",toupper(substr(s,length(s)))) - 1
sub(/.$/,"",s)
return num + (length(s) ? 16*hex2dec(s) : 0)
} '
- Output:
http%3A%2F%2Ffoo%20bar%2F http://foo bar/
OR:
LC_ALL=C
echo "http%3A%2F%2Ffoo%20bar%2F" | gawk -vRS='%[[:xdigit:]]{2}' '
RT {RT = sprintf("%c",strtonum("0x" substr(RT, 2)))}
{gsub(/+/," ");printf "%s", $0 RT}'
- Output:
http://foo bar/
BaCon
FUNCTION Url_Decode$(url$)
LOCAL result$
SPLIT url$ BY "%" TO item$ SIZE total
FOR x = 1 TO total-1
result$ = result$ & CHR$(DEC(LEFT$(item$[x], 2))) & MID$(item$[x], 3)
NEXT
RETURN item$[0] & result$
END FUNCTION
PRINT Url_Decode$("http%3A%2F%2Ffoo%20bar%2F")
PRINT Url_Decode$("google.com/search?q=%60Abdu%27l-Bah%C3%A1")
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
Bash
See #UNIX Shell
BBC BASIC
PRINT FNurldecode("http%3A%2F%2Ffoo%20bar%2F")
END
DEF FNurldecode(url$)
LOCAL i%
REPEAT
i% = INSTR(url$, "%", i%+1)
IF i% THEN
url$ = LEFT$(url$,i%-1) + \
\ CHR$EVAL("&"+FNupper(MID$(url$,i%+1,2))) + \
\ MID$(url$,i%+3)
ENDIF
UNTIL i% = 0
= url$
DEF FNupper(A$)
LOCAL A%,C%
FOR A% = 1 TO LEN(A$)
C% = ASCMID$(A$,A%)
IF C% >= 97 IF C% <= 122 MID$(A$,A%,1) = CHR$(C%-32)
NEXT
= A$
- Output:
http://foo bar/
Bracmat
( ( decode
= decoded hexcode notencoded
. :?decoded
& whl
' ( @(!arg:?notencoded "%" (% %:?hexcode) ?arg)
& !decoded !notencoded chr$(x2d$!hexcode):?decoded
)
& str$(!decoded !arg)
)
& out$(decode$http%3A%2F%2Ffoo%20bar%2F)
);
- Output:
http://foo bar/
C
#include <stdio.h>
#include <string.h>
inline int ishex(int x)
{
return (x >= '0' && x <= '9') ||
(x >= 'a' && x <= 'f') ||
(x >= 'A' && x <= 'F');
}
int decode(const char *s, char *dec)
{
char *o;
const char *end = s + strlen(s);
int c;
for (o = dec; s <= end; o++) {
c = *s++;
if (c == '+') c = ' ';
else if (c == '%' && ( !ishex(*s++) ||
!ishex(*s++) ||
!sscanf(s - 2, "%2x", &c)))
return -1;
if (dec) *o = c;
}
return o - dec;
}
int main()
{
const char *url = "http%3A%2F%2ffoo+bar%2fabcd";
char out[strlen(url) + 1];
printf("length: %d\n", decode(url, 0));
puts(decode(url, out) < 0 ? "bad string" : out);
return 0;
}
C#
using System;
namespace URLEncode
{
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine(Decode("http%3A%2F%2Ffoo%20bar%2F"));
}
private static string Decode(string uri)
{
return Uri.UnescapeDataString(uri);
}
}
}
- Output:
http://foo bar/
C++
#include <string>
#include "Poco/URI.h"
#include <iostream>
int main( ) {
std::string encoded( "http%3A%2F%2Ffoo%20bar%2F" ) ;
std::string decoded ;
Poco::URI::decode ( encoded , decoded ) ;
std::cout << encoded << " is decoded: " << decoded << " !" << std::endl ;
return 0 ;
}
- Output:
http%3A%2F%2Ffoo%20bar%2F is decoded: http://foo bar/ !
Caché ObjectScript
USER>Write $ZConvert("http%3A%2F%2Ffoo%20bar%2F", "I", "URL") http://foo bar/
Clojure
(java.net.URLDecoder/decode "http%3A%2F%2Ffoo%20bar%2F")
CoffeeScript
console.log decodeURIComponent "http%3A%2F%2Ffoo%20bar%2F?name=Foo%20Barson"
> coffee foo.coffee
http://foo bar/?name=Foo Barson
Common Lisp
(defun decode (string &key start)
(assert (char= (char string start) #\%))
(if (>= (length string) (+ start 3))
(multiple-value-bind (code pos)
(parse-integer string :start (1+ start) :end (+ start 3) :radix 16 :junk-allowed t)
(if (= pos (+ start 3))
(values (code-char code) pos)
(values #\% (1+ start))))
(values #\% (1+ start))))
(defun url-decode (url)
(loop with start = 0
for pos = (position #\% url :start start)
collect (subseq url start pos) into chunks
when pos
collect (multiple-value-bind (decoded next) (decode url :start pos)
(setf start next)
(string decoded))
into chunks
while pos
finally (return (apply #'concatenate 'string chunks))))
(url-decode "http%3A%2F%2Ffoo%20bar%2F")
- Output:
"http://foo bar/"
Crystal
require "uri"
puts URI.decode "http%3A%2F%2Ffoo%20bar%2F"
puts URI.decode "google.com/search?q=%60Abdu%27l-Bah%C3%A1"
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
D
import std.stdio, std.uri;
void main() {
writeln(decodeComponent("http%3A%2F%2Ffoo%20bar%2F"));
}
http://foo bar/
Delphi
program URLEncoding;
{$APPTYPE CONSOLE}
uses IdURI;
begin
Writeln(TIdURI.URLDecode('http%3A%2F%2Ffoo%20bar%2F'));
end.
Elixir
IO.inspect URI.decode("http%3A%2F%2Ffoo%20bar%2F")
IO.inspect URI.decode("google.com/search?q=%60Abdu%27l-Bah%C3%A1")
- Output:
"http://foo bar/" "google.com/search?q=`Abdu'l-Bahá"
Erlang
Built in.
34> http_uri:decode("http%3A%2F%2Ffoo%20bar%2F"). "http://foo bar/"
F#
open System
let decode uri = Uri.UnescapeDataString(uri)
[<EntryPoint>]
let main argv =
printfn "%s" (decode "http%3A%2F%2Ffoo%20bar%2F")
0
Factor
USING: io kernel urls.encoding ;
IN: rosetta-code.url-decoding
"http%3A%2F%2Ffoo%20bar%2F"
"google.com/search?q=%60Abdu%27l-Bah%C3%A1"
[ url-decode print ] bi@
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
Free Pascal
function urlDecode(data: String): AnsiString;
var
ch: Char;
pos, skip: Integer;
begin
pos := 0;
skip := 0;
Result := '';
for ch in data do begin
if skip = 0 then begin
if (ch = '%') and (pos < data.length -2) then begin
skip := 2;
Result := Result + AnsiChar(Hex2Dec('$' + data[pos+2] + data[pos+3]));
end else begin
Result := Result + ch;
end;
end else begin
skip := skip - 1;
end;
pos := pos +1;
end;
end;
FreeBASIC
Const alphanum = "0123456789abcdefghijklmnopqrstuvwxyz"
Function ToDecimal (cadena As String, base_ As Uinteger) As Uinteger
Dim As Uinteger i, n, result = 0
Dim As Uinteger inlength = Len(cadena)
For i = 1 To inlength
n = Instr(alphanum, Mid(Lcase(cadena),i,1)) - 1
n *= (base_^(inlength-i))
result += n
Next
Return result
End Function
Function url2string(cadena As String) As String
Dim As String c, nc, res
For j As Integer = 1 To Len(cadena)
c = Mid(cadena, j, 1)
If c = "%" Then
nc = Chr(ToDecimal((Mid(cadena, j+1, 2)), 16))
res &= nc
j += 2
Else
res &= c
End If
Next j
Return res
End Function
Dim As String URL = "http%3A%2F%2Ffoo%20bar%2F"
Print "Supplied URL '"; URL; "'"
Print "URL decoding '"; url2string(URL); "'"
URL = "google.com/search?q=%60Abdu%27l-Bah%C3%A1"
Print !"\nSupplied URL '"; URL; "'"
Print "URL decoding '"; url2string(URL); "'"
Sleep
Frink
While the default is to decode parameters as UTF-8 (which is the W3C recommendation,) the characters may have been encoded in another encoding scheme, and this can be handled correctly.
URLDecode["google.com/search?q=%60Abdu%27l-Bah%C3%A1","UTF8"]
Go
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
for _, escaped := range []string{
"http%3A%2F%2Ffoo%20bar%2F",
"google.com/search?q=%60Abdu%27l-Bah%C3%A1",
} {
u, err := url.QueryUnescape(escaped)
if err != nil {
log.Println(err)
continue
}
fmt.Println(u)
}
}
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
Groovy
assert URLDecoder.decode('http%3A%2F%2Ffoo%20bar%2F') == 'http://foo bar/'
Haskell
import qualified Data.Char as Char
urlDecode :: String -> Maybe String
urlDecode [] = Just []
urlDecode ('%':xs) =
case xs of
(a:b:xss) ->
urlDecode xss
>>= return . ((Char.chr . read $ "0x" ++ [a,b]) :)
_ -> Nothing
urlDecode ('+':xs) = urlDecode xs >>= return . (' ' :)
urlDecode (x:xs) = urlDecode xs >>= return . (x :)
main :: IO ()
main = putStrLn . maybe "Bad decode" id $ urlDecode "http%3A%2F%2Ffoo%20bar%2F"
- Output:
http://foo bar/
Another approach:
import Data.Char (chr)
import Data.List.Split (splitOn)
deCode :: String -> String
deCode url =
let ps = splitOn "%" url
in concat $
head ps :
((\(a, b) -> (chr . read) (mappend "0x" a) : b) <$> (splitAt 2 <$> tail ps))
-- TEST ------------------------------------------------------------------------
main :: IO ()
main = putStrLn $ deCode "http%3A%2F%2Ffoo%20bar%2F"
- Output:
http://foo bar/
Icon and Unicon
- Output:
encoded = "http%3A%2F%2Ffoo%20bar%2F" decoded = "http://foo bar/"
J
J does not have a native urldecode (until version 7 when the jhs
ide addon includes a jurldecode).
Here is an implementation:
require'strings convert'
urldecode=: rplc&(~.,/;"_1&a."2(,:tolower)'%',.toupper hfd i.#a.)
Example use:
urldecode 'http%3A%2F%2Ffoo%20bar%2F'
http://foo bar/
Note that an earlier implementation assumed the j6 implementation of hfd
which where hexadecimal letters resulting from hfd
were upper case. J8, in contrast, provides a lower case result from hfd. The addition of toupper
guarantees the case insensitivity required by RFC 3986 regardless of which version of J you are using. As the parenthesized expression containing hfd
is only evaluated at definition time, there's no performance penalty from the use of toupper
.
Example use:
urldecode 'google.com/search?q=%60Abdu%27l-Bah%C3%A1'
google.com/search?q=`Abdu'l-Bahá
Java
Java offers the URLDecoder and URLEncoder classes for this specific task.
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
URLDecoder.decode("http%3A%2F%2Ffoo%20bar%2F", StandardCharsets.UTF_8)
Alternately, you could use a regular expression capture
import java.util.regex.Matcher;
import java.util.regex.Pattern;
String decode(String string) {
Pattern pattern = Pattern.compile("%([A-Za-z\\d]{2})");
Matcher matcher = pattern.matcher(string);
StringBuilder decoded = new StringBuilder(string);
char character;
int start, end, offset = 0;
while (matcher.find()) {
character = (char) Integer.parseInt(matcher.group(1), 16);
/* offset the matched index since were adjusting the string */
start = matcher.start() - offset;
end = matcher.end() - offset;
decoded.replace(start, end, String.valueOf(character));
offset += 2;
}
return decoded.toString();
}
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
JavaScript
decodeURIComponent("http%3A%2F%2Ffoo%20bar%2F")
jq
If your jq already has "until", then the definition given below may be omitted.
# Emit . and stop as soon as "condition" is true.
def until(condition; next):
def u: if condition then . else (next|u) end;
u;
def url_decode:
# The helper function converts the input string written in the given
# "base" to an integer
def to_i(base):
explode
| reverse
| map(if 65 <= . and . <= 90 then . + 32 else . end) # downcase
| map(if . > 96 then . - 87 else . - 48 end) # "a" ~ 97 => 10 ~ 87
| reduce .[] as $c
# base: [power, ans]
([1,0]; (.[0] * base) as $b | [$b, .[1] + (.[0] * $c)]) | .[1];
. as $in
| length as $length
| [0, ""] # i, answer
| until ( .[0] >= $length;
.[0] as $i
| if $in[$i:$i+1] == "%"
then [ $i + 3, .[1] + ([$in[$i+1:$i+3] | to_i(16)] | implode) ]
else [ $i + 1, .[1] + $in[$i:$i+1] ]
end)
| .[1]; # answer
Example:
"http%3A%2F%2Ffoo%20bar%2F" | url_decode
- Output:
"http://foo bar/"
Julia
using URIParser
enc = "http%3A%2F%2Ffoo%20bar%2F"
dcd = unescape(enc)
println(enc, " => ", dcd)
- Output:
http%3A%2F%2Ffoo%20bar%2F => http://foo bar/
Kotlin
// version 1.1.2
import java.net.URLDecoder
fun main(args: Array<String>) {
val encoded = arrayOf("http%3A%2F%2Ffoo%20bar%2F", "google.com/search?q=%60Abdu%27l-Bah%C3%A1")
for (e in encoded) println(URLDecoder.decode(e, "UTF-8"))
}
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
Ksh
url_decode()
{
decode="${*//+/ }"
eval print -r -- "\$'${decode//'%'@(??)/'\'x\1"'\$'"}'" 2>/dev/null
}
url_decode "http%3A%2F%2Ffoo%20bar%2F"
url_decode "google.com/search?q=%60Abdu%27l-Bah%C3%A1"
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
Lambdatalk
Currently lambdatalk has no builtin primitive for decoding URLs. Let's define it using Javascript.
1) define a new javascript primitive:
{script
LAMBDATALK.DICT['decodeURIComponent'] = function() {
return decodeURIComponent( arguments[0].trim() );
};
}
2) and use it:
{decodeURIComponent http%3A%2F%2Ffoo%20bar%2F}
-> http://foo bar/
langur
val finish = fn s:b2s(map(fn x:number(x, 16), rest(split("%", s))))
val decode = fn s:replace(s, re/(%[0-9A-Fa-f]{2})+/, finish)
writeln decode("http%3A%2F%2Ffoo%20bar%2F")
writeln decode("google.com/search?q=%60Abdu%27l-Bah%C3%A1")
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
Lasso
bytes('http%3A%2F%2Ffoo%20bar%2F') -> decodeurl
-> http://foo bar/
Liberty BASIC
dim lookUp$( 256)
for i =0 to 256
lookUp$( i) ="%" +dechex$( i)
next i
url$ ="http%3A%2F%2Ffoo%20bar%2F"
print "Supplied URL '"; url$; "'"
print "As string '"; url2string$( url$); "'"
end
function url2string$( i$)
for j =1 to len( i$)
c$ =mid$( i$, j, 1)
if c$ ="%" then
nc$ =chr$( hexdec( mid$( i$, j +1, 2)))
url2string$ =url2string$ +nc$
j =j +2
else
url2string$ =url2string$ +c$
end if
next j
end function
Supplied URL 'http%3A%2F%2Ffoo%20bar%2F' As string 'http://foo bar/'
Lingo
----------------------------------------
-- URL decodes a string
-- @param {string} str
-- @return {string}
----------------------------------------
on urldecode (str)
res = ""
ba = bytearray()
len = str.length
repeat with i = 1 to len
c = str.char[i]
if (c = "%") then
-- fastest hex-to-dec conversion hack based on Lingo's rgb object
ba.writeInt8(rgb(str.char[i+1..i+2]).blue)
i = i + 2
else if (c = "+") then
ba.writeInt8(32)
else
ba.writeInt8(chartonum(c))
end if
end repeat
ba.position = 1
return ba.readRawString(ba.length)
end
put urldecode("http%3A%2F%2Ffoo%20bar%2F")
put urldecode("google.com/search?q=%60Abdu%27l-Bah%C3%A1")
- Output:
-- "http://foo bar/" -- "google.com/search?q=`Abdu'l-Bahá"
LiveCode
put urlDecode("http%3A%2F%2Ffoo%20bar%2F") & cr & \
urlDecode("google.com/search?q=%60Abdu%27l-Bah%C3%A1")
Results
http://foo bar/
google.com/search?q=`Abdu'l-Bah√°
Lua
function decodeChar(hex)
return string.char(tonumber(hex,16))
end
function decodeString(str)
local output, t = string.gsub(str,"%%(%x%x)",decodeChar)
return output
end
-- will print "http://foo bar/"
print(decodeString("http%3A%2F%2Ffoo%20bar%2F"))
M2000 Interpreter
Function Len(string) return length in words, so a value 1.5 means 3 bytes
We can add strings with half word at the end of a series of words.
A$=str$("A") has a length of 0.5
b$=chr$(a$) revert bytes to words adding zeroes after each character
Module CheckIt {
Function decodeUrl$(a$) {
DIM a$()
a$()=Piece$(a$, "%")
if len(a$())=1 then =str$(a$):exit
k=each(a$(),2)
\\ convert to one byte per character using str$(string)
acc$=str$(a$(0))
While k {
\\ chr$() convert to UTF16LE
\\ str$() convert to ANSI using locale (can be 1033 we can set it before as Locale 1033)
\\ so chr$(0x93) give 0x201C
\\ str$(chr$(0x93)) return one byte 93 in ANSI as string of one byte length
\\ numbers are for UTF-8 so we have to preserve them
acc$+=str$(Chr$(Eval("0x"+left$(a$(k^),2)))+Mid$(a$(k^),3))
}
=acc$
}
\\ decode from utf8
final$=DecodeUrl$("google.com/search?q=%60Abdu%27l-Bah%C3%A1")
Print string$(final$ as utf8dec)="google.com/search?q=`Abdu'l-Bahá"
final$=DecodeUrl$("http%3A%2F%2Ffoo%20bar%2F")
Print string$(final$ as utf8dec)="http://foo bar/"
}
CheckIt
Maple
StringTools:-Decode("http%3A%2F%2Ffoo%20bar%2F", encoding=percent);
- Output:
"http://foo bar/"
Mathematica/Wolfram Language
URLDecoding[url_] :=
StringReplace[url, "%" ~~ x_ ~~ y_ :> FromDigits[x ~~ y, 16]] //.
StringExpression[x___, Longest[n__Integer], y___] :>
StringExpression[x, FromCharacterCode[{n}, "UTF8"], y]
Example use:
URLDecoding["http%3A%2F%2Ffoo%20bar%2F"]
- Output:
http://foo bar/
Using the built-in URLDecode (http://reference.wolfram.com/language/ref/URLDecode.html) function:
- Output:
In[]:= URLDecode["http%3A%2F%2Ffoo%20bar%2F"] Out[]= "http://foo bar/" In[]:= URLDecode["google.com/search?q=%60Abdu%27l-Bah%C3%A1"] Out[]= "google.com/search?q=`Abdu'l-Bahá" In[]:= URLDecode[{"Kurt+G%C3%B6del", "Paul+Erd%C5%91s"}] Out[]= {"Kurt Gödel", "Paul Erdős"}
MATLAB / Octave
function u = urldecoding(s)
u = '';
k = 1;
while k<=length(s)
if s(k) == '%' && k+2 <= length(s)
u = sprintf('%s%c', u, char(hex2dec(s((k+1):(k+2)))));
k = k + 3;
else
u = sprintf('%s%c', u, s(k));
k = k + 1;
end
end
end
Usage:
octave:3> urldecoding('http%3A%2F%2Ffoo%20bar%2F') ans = http://foo bar/
NetRexx
/* NetRexx */
options replace format comments java crossref savelog symbols nobinary
url = [ -
'http%3A%2F%2Ffoo%20bar%2F', -
'mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E', -
'%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E' -
]
loop u_ = 0 to url.length - 1
say url[u_]
say DecodeURL(url[u_])
say
end u_
return
method DecodeURL(arg) public static
Parse arg encoded
decoded = ''
PCT = '%'
loop label e_ while encoded.length() > 0
parse encoded head (PCT) +1 code +2 tail
decoded = decoded || head
select
when code.strip('T').length() = 2 & code.datatype('X') then do
code = code.x2c()
decoded = decoded || code
end
when code.strip('T').length() \= 0 then do
decoded = decoded || PCT
tail = code || tail
end
otherwise do
nop
end
end
encoded = tail
end e_
return decoded
- Output:
http%3A%2F%2Ffoo%20bar%2F http://foo bar/ mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E mailto:"Ivan Aim" <ivan.aim@email.com> %6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E mailto:"Irma User" <irma.user@mail.com>
NewLISP
;; universal decoder, works for ASCII and UTF-8
;; (source http://www.newlisp.org/index.cgi?page=Code_Snippets)
(define (url-decode url (opt nil))
(if opt (replace "+" url " "))
(replace "%([0-9a-f][0-9a-f])" url (pack "b" (int $1 0 16)) 1))
(url-decode "http%3A%2F%2Ffoo%20bar%2F")
Nim
import cgi
echo decodeUrl("http%3A%2F%2Ffoo%20bar%2F")
- Output:
http://foo bar/
Oberon-2
MODULE URLDecoding;
IMPORT
URI := URI:String,
Out := NPCT:Console;
BEGIN
Out.String(URI.Unescape("http%3A%2F%2Ffoo%20bar%2F"));Out.Ln;
Out.String(URI.Unescape("google.com/search?q=%60Abdu%27l-Bah%C3%A1"));Out.Ln;
END URLDecoding.
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
Objeck
class UrlDecode {
function : Main(args : String[]) ~ Nil {
Net.UrlUtility->Decode("http%3A%2F%2Ffoo%20bar%2F")->PrintLine();
}
}
Objective-C
NSString *encoded = @"http%3A%2F%2Ffoo%20bar%2F";
NSString *normal = [encoded stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@", normal);
NSString *encoded = @"http%3A%2F%2Ffoo%20bar%2F";
NSString *normal = [encoded stringByRemovingPercentEncoding];
NSLog(@"%@", normal);
OCaml
Using the library ocamlnet from the interactive loop:
$ ocaml
# #use "topfind";;
# #require "netstring";;
# Netencoding.Url.decode "http%3A%2F%2Ffoo%20bar%2F" ;;
- : string = "http://foo bar/"
ooRexx
While the implementation shown for Rexx will also work with ooRexx, this version uses ooRexx syntax to invoke the built-in functions.
/* Rexx */
X = 0
url. = ''
X = X + 1; url.0 = X; url.X = 'http%3A%2F%2Ffoo%20bar%2F'
X = X + 1; url.0 = X; url.X = 'mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E'
X = X + 1; url.0 = X; url.X = '%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E'
Do u_ = 1 to url.0
Say url.u_
Say DecodeURL(url.u_)
Say
End u_
Exit
DecodeURL: Procedure
Parse Arg encoded
decoded = ''
PCT = '%'
Do label e_ while encoded~length() > 0
Parse Var encoded head (PCT) +1 code +2 tail
decoded = decoded || head
Select
when code~strip('T')~length() = 2 & code~datatype('X') then Do
code = code~x2c()
decoded = decoded || code
End
when code~strip('T')~length() \= 0 then Do
decoded = decoded || PCT
tail = code || tail
End
otherwise
Nop
End
encoded = tail
End e_
Return decoded
- Output:
http%3A%2F%2Ffoo%20bar%2F http://foo bar/ mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E mailto:"Ivan Aim" <ivan.aim@email.com> %6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E mailto:"Irma User" <irma.user@mail.com>
PascalABC.NET
uses System;
function URLDecode(s: string) := Uri.UnescapeDataString(s);
begin
Println(URLDecode('http%3A%2F%2Ffoo%20bar%2F'));
Println(URLDecode('google.com/search?q=%60Abdu%27l-Bah%C3%A1'));
Println(URLDecode('%25%32%35'));
end.
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá %25
Perl
sub urldecode {
my $s = shift;
$s =~ tr/\+/ /;
$s =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/eg;
return $s;
}
print urldecode('http%3A%2F%2Ffoo+bar%2F')."\n";
#!/usr/bin/perl -w
use strict ;
use URI::Escape ;
my $encoded = "http%3A%2F%2Ffoo%20bar%2F" ;
my $unencoded = uri_unescape( $encoded ) ;
print "The unencoded string is $unencoded !\n" ;
Phix
-- -- demo\rosetta\decode_url.exw -- =========================== -- with javascript_semantics function decode_url(string s) integer skip = 0 string res = "" for i=1 to length(s) do if skip then skip -= 1 else integer ch = s[i] if ch='%' then sequence scanres = {} if i+2<=length(s) then scanres = scanf("#"&s[i+1..i+2],"%x") end if if length(scanres)!=1 then return "decode error" end if skip = 2 ch = scanres[1][1] elsif ch='+' then ch = ' ' end if res &= ch end if end for return res end function printf(1,"%s\n",{decode_url("http%3A%2F%2Ffoo%20bar%2F")}) printf(1,"%s\n",{decode_url("google.com/search?q=%60Abdu%27l-Bah%C3%A1")}) {} = wait_key()
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
PHP
<?php
$encoded = "http%3A%2F%2Ffoo%20bar%2F";
$unencoded = rawurldecode($encoded);
echo "The unencoded string is $unencoded !\n";
?>
PicoLisp
: (ht:Pack (chop "http%3A%2F%2Ffoo%20bar%2F") T) -> "http://foo bar/"
Pike
void main()
{
array encoded_urls = ({
"http%3A%2F%2Ffoo%20bar%2F",
"google.com/search?q=%60Abdu%27l-Bah%C3%A1"
});
foreach(encoded_urls, string url) {
string decoded = Protocols.HTTP.uri_decode( url );
write( string_to_utf8(decoded) +"\n" ); // Assume sink does UTF8
}
}
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
PowerShell
[System.Web.HttpUtility]::UrlDecode("http%3A%2F%2Ffoo%20bar%2F")
- Output:
http://foo bar/
PureBasic
URL$ = URLDecoder("http%3A%2F%2Ffoo%20bar%2F")
Debug URL$ ; http://foo bar/
Python
#Python 2.X
import urllib
print urllib.unquote("http%3A%2F%2Ffoo%20bar%2F")
#Python 3.5+
from urllib.parse import unquote
print(unquote('http%3A%2F%2Ffoo%20bar%2F'))
R
URLdecode("http%3A%2F%2Ffoo%20bar%2F")
Racket
#lang racket
(require net/uri-codec)
(uri-decode "http%3A%2F%2Ffoo%20bar%2F")
Raku
(formerly Perl 6)
my @urls = < http%3A%2F%2Ffoo%20bar%2F
google.com/search?q=%60Abdu%27l-Bah%C3%A1 >;
say .subst( :g,
/ [ '%' ( <xdigit> ** 2 ) ]+ / ,
{ Blob.new((:16(~$_) for $0)).decode }
) for @urls;
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
Red
>> dehex "http%3A%2F%2Ffoo%20bar%2F"
== "http://foo bar/"
>> dehex "google.com/search?q=%60Abdu%27l-Bah%C3%A1"
== "google.com/search?q=`Abdu'l-Bahá"
Retro
This is provided by the casket library (used for web app development).
create buffer 32000 allot
{{
create bit 5 allot
: extract ( $c-$a ) drop @+ bit ! @+ bit 1+ ! bit ;
: render ( $c-$n )
dup '+ = [ drop 32 ] ifTrue
dup 13 = [ drop 32 ] ifTrue
dup 10 = [ drop 32 ] ifTrue
dup '% = [ extract hex toNumber decimal ] ifTrue ;
: <decode> ( $-$ ) repeat @+ 0; render ^buffer'add again ;
---reveal---
: decode ( $- ) buffer ^buffer'set <decode> drop ;
}}
"http%3A%2F%2Ffoo%20bar%2F" decode buffer puts
REXX
version 1
Tested with the ooRexx and Regina interpreters.
/* Rexx */
Do
X = 0
url. = ''
X = X + 1; url.0 = X; url.X = 'http%3A%2F%2Ffoo%20bar%2F'
X = X + 1; url.0 = X; url.X = 'mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E'
X = X + 1; url.0 = X; url.X = '%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E'
Do u_ = 1 to url.0
Say url.u_
Say DecodeURL(url.u_)
Say
End u_
Return
End
Exit
DecodeURL:
Procedure
Do
Parse Arg encoded
decoded = ''
PCT = '%'
Do while length(encoded) > 0
Parse Var encoded head (PCT) +1 code +2 tail
decoded = decoded || head
Select
When length(strip(code, 'T')) = 2 & datatype(code, 'X') then Do
code = x2c(code)
decoded = decoded || code
End
When length(strip(code, 'T')) \= 0 then Do
decoded = decoded || PCT
tail = code || tail
End
Otherwise Do
Nop
End
End
encoded = tail
End
Return decoded
End
Exit
- Output:
http%3A%2F%2Ffoo%20bar%2F http://foo bar/ mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E mailto:"Ivan Aim" <ivan.aim@email.com> %6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E mailto:"Irma User" <irma.user@mail.com>
version 2
This REXX version is identical to version 1, but with superfluous and dead code removed.
/*REXX program converts a URL─encoded string ──► its original unencoded form. */
url.1='http%3A%2F%2Ffoo%20bar%2F'
url.2='mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E'
url.3='%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E'
URLs =3
do j=1 for URLs
say url.j
say decodeURL(url.j)
say
end /*j*/
exit
/*──────────────────────────────────────────────────────────────────────────────────────*/
decodeURL: procedure; parse arg encoded; decoded= ''
do while encoded\==''
parse var encoded head '%' +1 code +2 tail
decoded= decoded || head
L= length( strip( code, 'T') )
select
when L==2 & datatype(code, "X") then decoded= decoded || x2c(code)
when L\==0 then do; decoded= decoded'%'
tail= code || tail
end
otherwise nop
end /*select*/
encoded= tail
end /*while*/
return decoded
- output is identical to the 1st REXX version.
version 3
This REXX version is a shorter version of version 2.
/*REXX program converts & displays a URL─encoded string ──► its original unencoded form.*/
url. =
url.1='http%3A%2F%2Ffoo%20bar%2F'
url.2='mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E'
url.3='%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E'
do j=1 until url.j==''; say /*process each URL; display blank line.*/
say url.j /*display the original URL. */
say URLdecode(url.j) /* " " decoded " */
end /*j*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
URLdecode: procedure; parse arg yyy /*get encoded URL from argument list. */
yyy= translate(yyy, , '+') /*a special case for an encoded blank. */
URL=
do until yyy==''
parse var yyy plain '%' +1 code +2 yyy
URL= URL || plain
if datatype(code, 'X') then URL= URL || x2c(code)
else URL= URL'%'code
end /*until*/
return URL
- output is identical to the 1st REXX version.
Ruby
Use any one of CGI.unescape
or URI.decode_www_form_component
. These methods also convert "+" to " ".
require 'cgi'
puts CGI.unescape("http%3A%2F%2Ffoo%20bar%2F")
# => "http://foo bar/"
require 'uri'
puts URI.decode_www_form_component("http%3A%2F%2Ffoo%20bar%2F")
# => "http://foo bar/"
URI.unescape
(alias URI.unencode
) still works. URI.unescape
is obsolete since Ruby 1.9.2 because of problems with its sibling URI.escape
.
Rust
const INPUT1: &str = "http%3A%2F%2Ffoo%20bar%2F";
const INPUT2: &str = "google.com/search?q=%60Abdu%27l-Bah%C3%A1";
fn append_frag(text: &mut String, frag: &mut String) {
if !frag.is_empty() {
let encoded = frag.chars()
.collect::<Vec<char>>()
.chunks(2)
.map(|ch| {
u8::from_str_radix(&ch.iter().collect::<String>(), 16).unwrap()
}).collect::<Vec<u8>>();
text.push_str(&std::str::from_utf8(&encoded).unwrap());
frag.clear();
}
}
fn decode(text: &str) -> String {
let mut output = String::new();
let mut encoded_ch = String::new();
let mut iter = text.chars();
while let Some(ch) = iter.next() {
if ch == '%' {
encoded_ch.push_str(&format!("{}{}", iter.next().unwrap(), iter.next().unwrap()));
} else {
append_frag(&mut output, &mut encoded_ch);
output.push(ch);
}
}
append_frag(&mut output, &mut encoded_ch);
output
}
fn main() {
println!("{}", decode(INPUT1));
println!("{}", decode(INPUT2));
}
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
Scala
import java.net.{URLDecoder, URLEncoder}
import scala.compat.Platform.currentTime
object UrlCoded extends App {
val original = """http://foo bar/"""
val encoded: String = URLEncoder.encode(original, "UTF-8")
assert(encoded == "http%3A%2F%2Ffoo+bar%2F", s"Original: $original not properly encoded: $encoded")
val percentEncoding = encoded.replace("+", "%20")
assert(percentEncoding == "http%3A%2F%2Ffoo%20bar%2F", s"Original: $original not properly percent-encoded: $percentEncoding")
assert(URLDecoder.decode(encoded, "UTF-8") == URLDecoder.decode(percentEncoding, "UTF-8"))
println(s"Successfully completed without errors. [total ${currentTime - executionStart} ms]")
}
Seed7
The library encoding.s7i defines functions to handle URL respectively percent encoding. The function fromPercentEncoded decodes a percend-encoded string. The function fromUrlEncoded works like fromPercentEncoded and additionally decodes '+' with a space. Both functions return byte sequences. To decode Unicode characters it is necessary to convert them from UTF-8 with fromUtf8 afterwards.
$ include "seed7_05.s7i";
include "encoding.s7i";
const proc: main is func
begin
writeln(fromPercentEncoded("http%3A%2F%2Ffoo%20bar%2F"));
writeln(fromUrlEncoded("http%3A%2F%2Ffoo+bar%2F"));
end func;
- Output:
http://foo bar/ http://foo bar/
Sidef
func urldecode(str) {
str.gsub!('+', ' ');
str.gsub!(/\%([A-Fa-f0-9]{2})/, {|a| 'C'.pack(a.hex)});
return str;
}
say urldecode('http%3A%2F%2Ffoo+bar%2F'); # => "http://foo bar/"
Swift
import Foundation
let encoded = "http%3A%2F%2Ffoo%20bar%2F"
if let normal = encoded.stringByReplacingPercentEscapesUsingEncoding(NSUTF8StringEncoding) {
println(normal)
}
Tcl
This code is careful to ensure that any untoward metacharacters in the input string still do not cause any problems.
proc urlDecode {str} {
set specialMap {"[" "%5B" "]" "%5D"}
set seqRE {%([0-9a-fA-F]{2})}
set replacement {[format "%c" [scan "\1" "%2x"]]}
set modStr [regsub -all $seqRE [string map $specialMap $str] $replacement]
return [encoding convertfrom utf-8 [subst -nobackslash -novariable $modStr]]
}
Demonstrating:
puts [urlDecode "http%3A%2F%2Ffoo%20bar%2F"]
- Output:
http://foo bar/
TUSCRIPT
$$ MODE TUSCRIPT
url_encoded="http%3A%2F%2Ffoo%20bar%2F"
BUILD S_TABLE hex=":%><:><2<>2<%:"
hex=STRINGS (url_encoded,hex), hex=SPLIT(hex)
hex=DECODE (hex,hex)
url_decoded=SUBSTITUTE(url_encoded,":%><2<>2<%:",0,0,hex)
PRINT "encoded: ", url_encoded
PRINT "decoded: ", url_decoded
- Output:
encoded: http%3A%2F%2Ffoo%20bar%2F decoded: http://foo bar/
UNIX Shell
urldecode() { local u="${1//+/ }"; printf '%b' "${u//%/\\x}"; }
Alternative: Replace printf '%b' "${u//%/\\x}"
with echo -e "${u//%/\\x}"
Example:
urldecode http%3A%2F%2Ffoo%20bar%2F
http://foo bar/
urldecode google.com/search?q=%60Abdu%27l-Bah%C3%A1
google.com/search?q=`Abdu'l-Bahároot@
function urldecode
{
typeset encoded=$1 decoded= rest= c= c1= c2=
typeset rest2= bug='rest2=${rest}'
if [[ -z ${BASH_VERSION:-} ]]; then
typeset -i16 hex=0; typeset -i8 oct=0
# bug /usr/bin/sh HP-UX 11.00
typeset _encoded='xyz%26xyz'
rest="${_encoded#?}"
c="${_encoded%%${rest}}"
if (( ${#c} != 1 )); then
typeset qm='????????????????????????????????????????????????????????????????????????'
typeset bug='(( ${#rest} > 0 )) && typeset -L${#rest} rest2="${qm}" || rest2=${rest}'
fi
fi
rest="${encoded#?}"
eval ${bug}
c="${encoded%%${rest2}}"
encoded="${rest}"
while [[ -n ${c} ]]; do
if [[ ${c} = '%' ]]; then
rest="${encoded#?}"
eval ${bug}
c1="${encoded%%${rest2}}"
encoded="${rest}"
rest="${encoded#?}"
eval ${bug}
c2="${encoded%%${rest2}}"
encoded="${rest}"
if [[ -z ${c1} || -z ${c2} ]]; then
c="%${c1}${c2}"
echo "WARNING: invalid % encoding: ${c}" >&2
elif [[ -n ${BASH_VERSION:-} ]]; then
c="\\x${c1}${c2}"
c=$(\echo -e "${c}")
else
hex="16#${c1}${c2}"; oct=hex
c="\\0${oct#8\#}"
c=$(print -- "${c}")
fi
elif [[ ${c} = '+' ]]; then
c=' '
fi
decoded="${decoded}${c}"
rest="${encoded#?}"
eval ${bug}
c="${encoded%%${rest2}}"
encoded="${rest}"
done
if [[ -n ${BASH_VERSION:-} ]]; then
\echo -E "${decoded}"
else
print -r -- "${decoded}"
fi
}
VBScript
Function RegExTest(str,patrn)
Dim regEx
Set regEx = New RegExp
regEx.IgnoreCase = True
regEx.Pattern = patrn
RegExTest = regEx.Test(str)
End Function
Function URLDecode(sStr)
Dim str,code,a0
str=""
code=sStr
code=Replace(code,"+"," ")
While len(code)>0
If InStr(code,"%")>0 Then
str = str & Mid(code,1,InStr(code,"%")-1)
code = Mid(code,InStr(code,"%"))
a0 = UCase(Mid(code,2,1))
If a0="U" And RegExTest(code,"^%u[0-9A-F]{4}") Then
str = str & ChrW((Int("&H" & Mid(code,3,4))))
code = Mid(code,7)
ElseIf a0="E" And RegExTest(code,"^(%[0-9A-F]{2}){3}") Then
str = str & ChrW((Int("&H" & Mid(code,2,2)) And 15) * 4096 + (Int("&H" & Mid(code,5,2)) And 63) * 64 + (Int("&H" & Mid(code,8,2)) And 63))
code = Mid(code,10)
ElseIf a0>="C" And a0<="D" And RegExTest(code,"^(%[0-9A-F]{2}){2}") Then
str = str & ChrW((Int("&H" & Mid(code,2,2)) And 3) * 64 + (Int("&H" & Mid(code,5,2)) And 63))
code = Mid(code,7)
ElseIf (a0<="B" Or a0="F") And RegExTest(code,"^%[0-9A-F]{2}") Then
str = str & Chr(Int("&H" & Mid(code,2,2)))
code = Mid(code,4)
Else
str = str & "%"
code = Mid(code,2)
End If
Else
str = str & code
code = ""
End If
Wend
URLDecode = str
End Function
url = "http%3A%2F%2Ffoo%20bar%C3%A8%2F"
WScript.Echo "Encoded URL: " & url & vbCrLf &_
"Decoded URL: " & UrlDecode(url)
- Output:
Encoded URL: http%3A%2F%2Ffoo%20bar%C3%A8%2F Decoded URL: http://foo barè/
V (Vlang)
import net.urllib
fn main() {
for escaped in [
"http%3A%2F%2Ffoo%20bar%2F",
"google.com/search?q=%60Abdu%27l-Bah%C3%A1",
] {
u := urllib.query_unescape(escaped)?
println(u)
}
}
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
Wren
import "./fmt" for Conv
var urlDecode = Fn.new { |enc|
var res = ""
var i = 0
while (i < enc.count) {
var c = enc[i]
if (c == "\%") {
var b = Conv.atoi(enc[i+1..i+2], 16)
res = res + String.fromByte(b)
i = i + 3
} else {
res = res + c
i = i + 1
}
}
return res
}
// We need to escape % characters in Wren as % is otherwise used for string interpolation.
var encs = [
"http\%3A\%2F\%2Ffoo\%20bar\%2F",
"google.com/search?q=\%60Abdu\%27l-Bah\%C3\%A1"
]
for (enc in encs)System.print(urlDecode.call(enc))
- Output:
http://foo bar/ google.com/search?q=`Abdu'l-Bahá
XPL0
code Text=12;
string 0; \use zero-terminated strings
func Decode(S0); \Decode URL string and return its address
char S0;
char S1(80); \BEWARE: very temporary string space returned
int C, N, I, J;
[I:= 0; J:= 0;
repeat C:= S0(I); I:= I+1; \get char
if C=^% then \convert hex to char
[C:= S0(I); I:= I+1;
if C>=^a then C:= C & ~$20; \convert to uppercase
N:= C - (if C<=^9 then ^0 else ^A-10);
C:= S0(I); I:= I+1;
if C>=^a then C:= C & ~$20;
C:= N*16 + C - (if C<=^9 then ^0 else ^A-10);
];
S1(J):= C; J:= J+1; \put char in output string
until C=0;
return S1;
];
Text(0, Decode("http%3A%2F%2Ffoo%20bar%2f"))
- Output:
http://foo bar/
Yabasic
sub decode_url$(s$)
local res$, ch$
while(s$ <> "")
ch$ = left$(s$, 1)
if ch$ = "%" then
ch$ = chr$(dec(mid$(s$, 2, 2)))
s$ = right$(s$, len(s$) - 3)
else
if ch$ = "+" ch$ = " "
s$ = right$(s$, len(s$) - 1)
endif
res$ = res$ + ch$
wend
return res$
end sub
print decode_url$("http%3A%2F%2Ffoo%20bar%2F")
print decode_url$("google.com/search?q=%60Abdu%27l-Bah%C3%A1")
zkl
"http%3A%2F%2Ffoo%20bar%2F".pump(String, // push each char through these fcns:
fcn(c){ if(c=="%") return(Void.Read,2); return(Void.Skip,c) },// %-->read 2 chars else pass through
fcn(_,b,c){ (b+c).toInt(16).toChar() }) // "%" (ignored) "3"+"1"-->0x31-->"1"
- Output:
http://foo bar/
or use libCurl:
var Curl=Import.lib("zklCurl");
Curl.urlDecode("http%3A%2F%2Ffoo%20bar%2F");
- Output:
http://foo bar/
- Programming Tasks
- Solutions by Programming Task
- String manipulation
- 11l
- ABAP
- Action!
- Ada
- AWS
- ALGOL 68
- Apex
- AppleScript
- AppleScript Toolbox
- Arturo
- AutoHotkey
- AWK
- BaCon
- Bash
- BBC BASIC
- Bracmat
- C
- C sharp
- C++
- Poco
- Caché ObjectScript
- Clojure
- CoffeeScript
- Common Lisp
- Crystal
- D
- Delphi
- Elixir
- Erlang
- F Sharp
- Factor
- Free Pascal
- FreeBASIC
- Frink
- Go
- Groovy
- Haskell
- Icon
- Unicon
- Icon Programming Library
- J
- Java
- JavaScript
- Jq
- Julia
- Kotlin
- Ksh
- Lambdatalk
- Langur
- Lasso
- Liberty BASIC
- Lingo
- LiveCode
- Lua
- M2000 Interpreter
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Octave
- NetRexx
- NewLISP
- Nim
- Oberon-2
- Objeck
- Objective-C
- OCaml
- OoRexx
- PascalABC.NET
- Perl
- Phix
- PHP
- PicoLisp
- Pike
- PowerShell
- PureBasic
- Python
- R
- Racket
- Raku
- Red
- Retro
- REXX
- Ruby
- Rust
- Scala
- Seed7
- Sidef
- Swift
- Tcl
- TUSCRIPT
- UNIX Shell
- VBScript
- V (Vlang)
- Wren
- Wren-fmt
- XPL0
- Yabasic
- Zkl