How can I "URL decode" a string in Emacs Lisp?
Asked Answered
I

6

33

I've got a string like "foo%20bar" and I want "foo bar" out of it.

I know there's got to be a built-in function to decode a URL-encoded string (query string) in Emacs Lisp, but for the life of me I can't find it today, either in my lisp/ folder or with Google.

What is it called?

Ingeringersoll answered 4/3, 2009 at 18:24 Comment(0)
W
6

org-link-unescape does the job for very simple cases ... w3m-url-decode-string is better, but it isn't built in and the version I have locally isn't working with Emacs 23.

Wiretap answered 4/3, 2009 at 20:31 Comment(2)
That's good enough for now. It is strange that it uses only a constant list of 17 chars, though. Maybe I'll fix that sometime.Ingeringersoll
url-unhex-string does what you want.Eddyede
P
50
url-unhex-string
Pythagoreanism answered 5/3, 2009 at 8:6 Comment(2)
I've got a url-unhex-string no match with Emacs 25 :/Lemay
You may need to (require 'url-util) -- in practice, this will often be done by some other code loading but certainly not good to rely on that.Wiretap
R
30

In my case I needed to do this interactively. The previous answers gave me the right functions to call, then it was just a matter of wrapping it a little to make them interactive:

(defun func-region (start end func)
  "run a function over the region between START and END in current buffer."
  (save-excursion
    (let ((text (delete-and-extract-region start end)))
      (insert (funcall func text)))))

(defun hex-region (start end)
  "urlencode the region between START and END in current buffer."
  (interactive "r")
  (func-region start end #'url-hexify-string))

(defun unhex-region (start end)
  "de-urlencode the region between START and END in current buffer."
  (interactive "r")
  (func-region start end #'url-unhex-string))

Add salt, I mean bind to keys according to taste.

Rollet answered 30/6, 2011 at 21:3 Comment(0)
D
11

Emacs is shipped with a URL library that provides a bunch of URL parsing functions—as huaiyuan and Charlie Martin already pointed out. Here is a small example that'd give you an idea how to use it:

(let ((url "http://www.google.hu/search?q=elisp+decode+url&btnG=Google+keres%E9s&meta="))
  ;; Return list of arguments and values
  (url-parse-query-string
   ;; Decode hexas
   (url-unhex-string
    ;; Retrieve argument list
    (url-filename
     ;; Parse URL, return a struct
     (url-generic-parse-url url)))))
=> (("meta" "") ("btnG" "Google+keresés") ("/search?q" "elisp+decode+url"))

I think is better to rely on it rather than Org-mode as it is its main purpose to parse a URL.

Depriest answered 28/4, 2009 at 12:8 Comment(1)
love this example!Cretaceous
W
6

org-link-unescape does the job for very simple cases ... w3m-url-decode-string is better, but it isn't built in and the version I have locally isn't working with Emacs 23.

Wiretap answered 4/3, 2009 at 20:31 Comment(2)
That's good enough for now. It is strange that it uses only a constant list of 17 chars, though. Maybe I'll fix that sometime.Ingeringersoll
url-unhex-string does what you want.Eddyede
L
3

You can grab urlenc from MELPA and use urlenc:decode-region for a region or urlenc:decode-insert to insert your text interactively.

Littlest answered 24/5, 2021 at 11:32 Comment(0)
B
0

I think you're making it a little too hard: split-string will probably do most of what you want. For fancier stuff, have a look at the functions in url-expand.el; unfortunately, many of them don't have doc-strings, so you may have to read code.

url-generic-parse-url looks like a potential winner.

Boss answered 4/3, 2009 at 18:44 Comment(1)
Hmm, maybe I misspoke. I've got a string like "foo%20bar" and I want "foo bar" out of it. I don't see how split-string or url-generic-parse-url or anything in url-expand.el really helps here.Ingeringersoll

© 2022 - 2024 — McMap. All rights reserved.