在emacs中交换值

Ado*_*obe 1 emacs elisp

这是一个交换值的Find-Replace:

Find: right\|left
Repl: \,(if (equal "right" \&) "left" "right")
Run Code Online (Sandbox Code Playgroud)

这是尝试将其转换为交互功能:

(defun swaps (rit lft)
  "Swaps rit to lft."
  (interactive "sChange this: 
sTo this: ")
  (save-excursion
    (goto-char (region-beginning))
    (while (search-forward-regexp ("%s\\|%s" rit lft) nil t) 
      (replace-match (if (equal rit \\&) lft rit) t nil))))
Run Code Online (Sandbox Code Playgroud)

我也试过rit\\|lftrit\|lft不是("%s\\|%s" rit lft)......

编辑:

答案是:

(defun swaps (rit lft)
  "Swaps rit to lft."
  (interactive "sChange this: 
sTo this: ")
  (save-excursion
    (goto-char (region-beginning))
    (while  (search-forward-regexp (format "%s\\|%s" 
                                          (regexp-quote rit)
                                          (regexp-quote lft)) (region-end) t) 
      (replace-match (if (equal rit (match-string 0)) lft rit) t nil))))
Run Code Online (Sandbox Code Playgroud)

Jon*_* O. 5

("%s\\|%s" rit lft)不是一个有效的Lisp表达式:当它被评估时,Emacs会抱怨这"%s\\|%s"不是一个函数.你可能想做

 (format "%s\\|%s" rit lft)
Run Code Online (Sandbox Code Playgroud)

regexp-quote如果你的字符串包含regexp特殊字符,最好使用它:

(format "%s\\|%s" 
        (regexp-quote rit)
        (regexp-quote lft))
Run Code Online (Sandbox Code Playgroud)

或者,您也可以使用该regexp-opt函数,该函数构造一个有效的正则表达式来匹配字符串列表中的任何一个:

(regexp-opt (list rit lft))
Run Code Online (Sandbox Code Playgroud)

\\&仅表示一个替换参数内的匹配的字符串replace-regexp,replace-match和类似的功能.在其他Lisp代码中,您需要使用(match-string 0).

最后,如果你只想让它在这个区域上工作,你应该提供它(region-end)作为第二个参数search-forward-regexp.