UNICODE アンエスケープする

以下の環境で動作確認しました。

文字列を UNICODE アンエスケープします。
*unescape-unicode-string-default-regexp* は、デフォルトのアンエスケープする文字列にマッチする正規表現です。後述する *unescape-unicode-string-regexp-alist* で、正規表現を決定できなかった場合に使用されます。この変数には、以下の要素からなるリストをセットします。

第 1 要素
エスケープされた文字列にマッチする正規表現
第 2 要素以降
後方参照する数値のグループ番号と基数のペア

正規表現は大文字小文字を区別します。大文字小文字を区別しないときは、関数 compile-regexp の第 2 引数に、t を指定してコンパイルした正規表現をセットしてください。
*unescape-unicode-string-regexp-alist* は、正規表現の連想リストで、関数と *unescape-unicode-string-default-regexp* と同様のリストのペアをセットします。先頭の要素から関数を実行し、関数が non-nil を返した要素の正規表現を使用します。

以下の正規表現が定義済みです。

html-mode,
//www1.odn.ne.jp/ymtz/html_plus-mode.html">html+-mode, xml-mode のマイナーモード XHTML1.0/1.1:『&#\(?:\([0-9]+\)\|x\([0-9a-f]+\)\);』(大文字小文字を区別しない)
//www.geocities.jp/kiaswebsite/xyzzy/jscript-mode.html" title="kia's website - xyzzy関連 - jscript-mode.l">jscript-mode:『\\u\([0-9A-F]\{4\}\)』
デフォルト
『%u\([0-9A-F]\{4\}\)』

コード

;; 文字列を UNICODE アンエスケープする

; デフォルトの正規表現
; 第 1 要素にアンエスケープする文字列にマッチする正規表現
; 第 2 要素以降に取り出す数値のグループ番号と基数をペアにしたコンスセル
; 正規表現は大文字小文字を区別する
; 大文字小文字を区別しないようにするには compile-regexp の第 2 引数に t を指定
; してコンパイルした正規表現をセットする
(defvar *unescape-unicode-string-default-regexp*
  `(,(compile-regexp "%u\\([0-9A-F]\\{4\\}\\)") (1 . 16)))

; 正規表現の連想リスト
; car の関数が non-nil を返すとき cdr の正規表現を使用する
(defvar *unescape-unicode-string-regexp-alist*
  `((,#'(lambda ()
          (or (member buffer-mode '("html-mode" "html+-mode") :test #'string=)
              (and (string= buffer-mode "xml-mode")
                   (string-match "^xml:XHTML1\\.\\(?:0-\\(?:Strict\\|Frameset\\|Transitional\\)\\|1\\)$"
                                 mode-name))))
     . (,(compile-regexp "&#\\(?:\\([0-9]+\\)\\|x\\([0-9a-f]+\\)\\);" t)
        (1 . 10) (2 . 16)))
    (,#'(lambda () (string= buffer-mode "jscript-mode"))
     . (,(compile-regexp "\\\\u\\([0-9A-F]\\{4\\}\\)")
        (1 . 16)))
    ))

(defun unescape-unicode-string (str)
  (let* ((lst (or (some #'(lambda (x) (if (funcall (car x)) (cdr x)))
                        *unescape-unicode-string-regexp-alist*)
                  *unescape-unicode-string-default-regexp*))
         (re (car lst))
         (alst (cdr lst))
         (getc (if (= (list-length alst) 1)
                   (let ((n (caar alst))
                         (r (cdar alst)))
                     #'(lambda () (parse-integer (match-string n) :radix r)))
                 (let ((pint #'(lambda (x)
                                 (let ((str (match-string (car x))))
                                   (if str (parse-integer str :radix (cdr x)))))))
                   #'(lambda () (some pint alst)))))
         (tmpb (create-new-buffer " *work*"))
         code)
    (set-buffer tmpb)
    (unwind-protect
        (progn
          (insert str)
          (goto-char (point-min))
          (while (scan-buffer re :tail t :regexp t)
            (when (setq code (funcall getc))
              (delete-region (match-beginning 0) (match-end 0))
              (insert (format nil "~C" (unicode-char code)))))
          (buffer-substring (point-min) (point-max)))
      (if tmpb (delete-buffer tmpb)))))

; リージョンを UNICODE アンエスケープする
(defun unescape-unicode-string-region (from to)
  (interactive "*r")
  (let ((str (unescape-unicode-string (buffer-substring from to))))
    (delete-region from to)
    (insert str)))

; セレクションを UNICODE アンエスケープする
(defun unescape-unicode-string-selection ()
  (interactive "*")
  (case (get-selection-type)
    ((1 2)
     (ed::map-selection #'(lambda (start end)
                            (unescape-unicode-string-region start end))))
    (3 (error "セレクションが矩形選択です"))
    (t (error "セレクションがありません"))))