经常在 Emacs 里编辑东西的时候,需要把某个字符串替换成其它字符串。一般情况下,只需要用 M-x replace-string 这个命令就可以实现这一操作。

但是当你要替换的字符串的正则表达式比较复杂,且你经常需要在不同的 buffer 引用这一操作的时候,最好的方法还是把这个操作保存到你的 elisp 函数里。每次要用,调用这个 elisp 函数即可。

程序非常的简单,核心的内容就是 re-search-forward 和 replace-match 这两个 elisp 的内置函数。

(while (re-search-forward "foo[ \t]+bar" nil t)
(replace-match "foobar"))

当然,re-search-forward 只会往前搜索当前 buffer,如果你要往后搜,则要用 re-search-backward 这个函数。这两个函数合起来用,就成了一个全文搜索、替换的函数了。例如下面的代码就是把 buffer 里所有的 endtime 字符串替换成当前的时间戳:

(defun endtime ()
(interactive)

  (while (re-search-backward "mendtime" nil t)
(replace-match (format-time-string "%4Y-%2m-%2d %H:%M:%S")))

  (while (re-search-forward "mendtime" nil t)
(replace-match (format-time-string "%4Y-%2m-%2d %H:%M:%S"))))

当然,如果你需要全文替换的话,更优雅的解决办法是这样的:

(defun endtime ()
(interactive)
(save-excursion
(goto-char (point-min))
(while (re-search-forward "mendtime" nil t)
(replace-match (format-time-string "%4Y-%2m-%2d %H:%M:%S")))))