在emacs中交换值

时间:2012-02-27 11:09:51

标签: emacs elisp

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

Find: right\|left
Repl: \,(if (equal "right" \&) "left" "right")

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

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

我还尝试了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))))

1 个答案:

答案 0 :(得分:5)

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

 (format "%s\\|%s" rit lft)

如果您的字符串包含正则表达式特殊字符,最好使用regexp-quote

(format "%s\\|%s" 
        (regexp-quote rit)
        (regexp-quote lft))

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

(regexp-opt (list rit lft))

\\&仅代表replace-regexpreplace-match和类似函数的替换参数中的匹配字符串。在其他Lisp代码中,您需要使用(match-string 0)

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