⚠️ Warning: This is a draft ⚠️

This means it might contain formatting issues, incorrect code, conceptual problems, or other severe issues.

If you want to help to improve and eventually enable this page, please fork RosettaGit's repository and open a merge request on GitHub.

{{task}} [[Category:String manipulation]]

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á".

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.

Ada

{{libheader|AWS}}

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;

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

{{libheader|AppleScript Toolbox}}

AST URL decode "google.com/search?q=%60Abdu%27l-Bah%C3%A1"

Arturo

url1 "http%3A%2F%2Ffoo%20bar%2F"
print $(decodeUrl url1)

url2 "google.com/search?q=%60Abdu%27l-Bah%C3%A1"
print $(decodeUrl url2)

{{out}}

http://foo bar/
google.com/search?q=`Abdu'l-Bahá

AutoHotkey

encURL := "http%3A%2F%2Ffoo%20bar%2F"
SetFormat, Integer, hex
Loop Parse, encURL
   If A_LoopField = `%
      reading := 2, read := ""
   else if reading
   {
      read .= A_LoopField, --reading
      if not reading
         out .= Chr("0x" . read)
   }
   else out .= A_LoopField
MsgBox % out ; http://foo bar/

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)
} '

{{out}}


http%3A%2F%2Ffoo%20bar%2F
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")

{{out}}


http://foo bar/
google.com/search?q=`Abdu'l-Bahá

BBC BASIC

{{works with|BBC BASIC for Windows}}

      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$

{{out}}


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)
);

{{out}}

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++

{{libheader|Poco}} {{works with|g++}}

#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 ;
}

{{out}}

http%3A%2F%2Ffoo%20bar%2F is decoded: http://foo bar/ !

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);
        }
    }
}

{{out}}


http://foo bar/

=={{header|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


```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")

{{out}}

"http://foo bar/"

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")

{{out}}


"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/"

=={{header|F_Sharp|F#}}== {{trans|C#}}

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@

{{out}}


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;

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)
	}
}

{{out}}


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"

{{out}}

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"

{{Out}}

http://foo bar/

=={{header|Icon}} and {{header|Unicon}}==

link hexcvt

procedure main()
ue := "http%3A%2F%2Ffoo%20bar%2F"
ud := decodeURL(ue) | stop("Improperly encoded string ",image(ue))
write("encoded = ",image(ue))
write("decoded = ",image(ue))
end

procedure decodeURL(s)              #: decode URL/URI encoded data
static de
initial {                           # build lookup table for everything
  de := table()
  every de[hexstring(ord(c := !string(&ascii)),2)] := c
  }

c := ""
s ? until pos(0) do                 # decode every %xx or fail
   c ||:= if ="%" then \de[move(2)] | fail
   else move(1)
return c
end

{{libheader|Icon Programming Library}} [http://www.cs.arizona.edu/icon/library/src/procs/hexcvt.icn hexcvt provides hexstring]

{{out}}

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 [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 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

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

public class Main
{
    public static void main(String[] args) throws UnsupportedEncodingException
    {
        String encoded = "http%3A%2F%2Ffoo%20bar%2F";
        String normal = URLDecoder.decode(encoded, "utf-8");
        System.out.println(normal);
    }
}

{{out}}

http://foo bar/

JavaScript

decodeURIComponent("http%3A%2F%2Ffoo%20bar%2F")

jq

{{works with|jq|1.4}} 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

{{out}}


"http://foo bar/"

Julia


using URIParser

enc = "http%3A%2F%2Ffoo%20bar%2F"

dcd = unescape(enc)

println(enc, " => ", dcd)

{{out}}


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"))
}

{{out}}


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")

{{Out}}


-- "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")

Resultshttp://foo bar/ google.com/search?q=`Abdu'l-Bah√°




## Lua


```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);

{{Out}}

                           "http://foo bar/"

Mathematica

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"]

{{out}}

http://foo bar/

=={{header|MATLAB}} / {{header|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

{{out}}

http%3A%2F%2Ffoo%20bar%2F
http://foo bar/

mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E
mailto:"Ivan Aim" 

%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" 

```



## NewLISP


```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


```nim
import cgi

echo decodeUrl("http%3A%2F%2Ffoo%20bar%2F")
```


=={{header|Oberon-2}}==
{{works with|oo2c}}

```oberon2

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.

```

{{out}}

```txt

http://foo bar/
google.com/search?q=`Abdu'l-Bahá

```



## Objeck


```objeck

class UrlDecode {
  function : Main(args : String[]) ~ Nil {
    Net.UrlUtility->Decode("http%3A%2F%2Ffoo%20bar%2F")->PrintLine();
  }
}

```


=={{header|Objective-C}}==

```objc
NSString *encoded = @"http%3A%2F%2Ffoo%20bar%2F";
NSString *normal = [encoded stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@", normal);
```

{{works with|Mac OS X|10.9+}}{{works with|iOS|7+}}

```objc
NSString *encoded = @"http%3A%2F%2Ffoo%20bar%2F";
NSString *normal = [encoded stringByRemovingPercentEncoding];
NSLog(@"%@", normal);
```



## OCaml


Using the library [http://projects.camlcity.org/projects/ocamlnet.html ocamlnet] from the interactive loop:


```ocaml
$ ocaml
# #use "topfind";;
# #require "netstring";;

# Netencoding.Url.decode "http%3A%2F%2Ffoo%20bar%2F" ;;
- : string = "http://foo bar/"
```


== {{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.

```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
```


{{out}}

```txt

http%3A%2F%2Ffoo%20bar%2F
http://foo bar/

mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E
mailto:"Ivan Aim" 

%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" 

```



## Perl



```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";

```



```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" ;
```



## Perl 6


```perl6
my $url = "http%3A%2F%2Ffoo%20bar%2F";

say $url.subst: :g,
    /'%'(<:hexdigit>**2)/,
    ->  ($ord          ) { chr(:16(~$ord)) }

# Alternately, you can use an in-place substitution:
$url ~~ s:g[ '%' (<:hexdigit> ** 2) ] = chr :16(~$0);
say $url;
```



## Phix


```Phix
--
-- demo\rosetta\decode_url.exw
--
### =====================

--
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")})
```

{{Out}}

```txt

http://foo bar/
google.com/search?q=`Abdu'l-Bahá

```



## PHP


```php

```



## PicoLisp


```txt
: (ht:Pack (chop "http%3A%2F%2Ffoo%20bar%2F") T)
-> "http://foo bar/"
```



## PowerShell


```PowerShell

[System.Web.HttpUtility]::UrlDecode("http%3A%2F%2Ffoo%20bar%2F")

```

{{Out}}

```txt

http://foo bar/

```



## PureBasic


```PureBasic
URL$ = URLDecoder("http%3A%2F%2Ffoo%20bar%2F")

Debug URL$  ; http://foo bar/
```



## Python


```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



```R
URLdecode("http%3A%2F%2Ffoo%20bar%2F")
```



## Racket



```racket

#lang racket
(require net/uri-codec)
(uri-decode "http%3A%2F%2Ffoo%20bar%2F")

```



## Retro

This is provided by the '''casket''' library (used for web app development).


```Retro
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 ;
  :  (  $-$  ) repeat @+ 0; render ^buffer'add again ;
---reveal---
  : decode   (  $-   ) buffer ^buffer'set  drop ;
}}

"http%3A%2F%2Ffoo%20bar%2F" decode buffer puts
```



## REXX


### version 1

{{Trans|ooRexx}}
Tested with the ooRexx and Regina interpreters.

```REXX
/* 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

```


{{out}}

```txt

http%3A%2F%2Ffoo%20bar%2F
http://foo bar/

mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E
mailto:"Ivan Aim" 

%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" 

```



### version 2

This REXX version is identical to version 1, but with superfluous and dead code removed.

```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
```

{{out|output|text=  is identical to the 1st REXX version.}}


### version 3

This REXX version is a shorter version of version 2.

```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
```

{{out|output|text=  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 " ".


```ruby
require 'cgi'
puts CGI.unescape("http%3A%2F%2Ffoo%20bar%2F")
# => "http://foo bar/"
```


{{works with|Ruby|1.9.2}}

```ruby
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


```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::>()
            .chunks(2)
            .map(|ch| {
                u8::from_str_radix(&ch.iter().collect::(), 16).unwrap()
            }).collect::>();
        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));
}
```

{{out}}

```txt

http://foo bar/
google.com/search?q=`Abdu'l-Bahá

```



## Scala

{{libheader|Scala}}
```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 [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 ''utf8ToStri'' afterwards.

```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;
```


{{out}}

```txt

http://foo bar/
http://foo bar/

```



## Sidef

{{trans|Perl}}

```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/"
```



## Swift


```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.

```tcl
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:

```tcl
puts [urlDecode "http%3A%2F%2Ffoo%20bar%2F"]
```

{{out}}

```txt
http://foo bar/
```


## TUSCRIPT


```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

```

{{out}}

```txt

encoded: http%3A%2F%2Ffoo%20bar%2F
decoded: http://foo bar/

```



## UNIX Shell


{{works with|bash}}
{{works with|ksh}}


```bash
urldecode() { local u="${1//+/ }"; printf '%b' "${u//%/\\x}"; }
```


Example:


```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@

```





```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
}

```



## VBScript


```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)
```


{{out}}

```txt
Encoded URL: http%3A%2F%2Ffoo%20bar%C3%A8%2F
Decoded URL: http://foo barè/
```



## XPL0


```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"))
```


{{out}}

```txt

http://foo bar/

```



## Yabasic

{{trans|Phix}}

```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


```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"
```

{{out}}

```txt
http://foo bar/
```

or use libCurl:

```zkl
var Curl=Import.lib("zklCurl");
Curl.urlDecode("http%3A%2F%2Ffoo%20bar%2F");
```

{{out}}
```txt
http://foo bar/
```