意外に適切なライブラリがありません。そのため、自分で書いてしまったりしがちです。
application/x-www-form-urlencodedに限ればDrakmaやURL-REWRITEのurl-encodeが使えますが、
(drakma:url-encode "a b+c$d(e)f/" :utf-8)
;=> "a+b%2Bc$d(e)f%2F"
空白を+に変換してしまうため、URIのパスコンポーネントやフラグメントコンポーネントにはそのまま流用できません。
Hunchentootのurl-encodeはパスコンポーネントなどにも使うことができますが、URIのエンコーディングのためにウェブサーバをロードするのに抵抗を感じる場合があるかもしれません。
(hunchentoot:url-encode "a b+c$d(e)f/")
;=> "a%20b%2Bc$d(e)f%2F"
また、こちらはDrakmaなどと対照的に、パーセントエンコーディングだけに対応していて、application/x-www-form-urlencodedには対応していません。この辺りの違いは、サーバとクライアントという両者の違いによるものと思われます。
予約文字などを割と真面目に処理してくれるのはPuriのencode-escaped-encodingですが、エクスポートされていない内部関数という扱いです。こちらもパーセントエンコーディングにのみ対応しています。
(puri::encode-escaped-encoding "a b+c$d(e)f/"
puri::*reserved-path-characters*
t)
;=> "a%20b+c$d(e)f%2f"
また、バージョン1.5.4の時点では128以上のオクテットを素通ししてしまうバグがあります。
(puri::encode-escaped-encoding "日本語"
puri::*reserved-path-characters*
t)
;=> "日本語"
SBCLに依存しても構わなければ、URLエンコード/デコード - sileの日記も利用できます。