做一些算术与elisp中的regexp搜索结果

时间:2012-12-13 19:35:43

标签: emacs elisp

前一段时间@Oleg Pavliv在https://unix.stackexchange.com/questions/47615/emacs-simple-arithmetics-in-query-replace中解释了如何在emacs中进行查询替换(交互式)中的简单算术。

现在我想对一个小的elisp程序使用相同的方法,但它不起作用。例如,考虑以下elisp代码的最小示例:

(defun Nshift ()
(interactive)
(query-replace-regexp "\\([0-9]+\\)\\.Number" "\\,((+ 3 \\#1)).Number")
)

现在假设我在包含例如字符串Nshift的缓冲区中运行4.Number,然后我收到以下错误消息。

match-substitute-replacement: Invalid use of `\' in replacement text

Nshift的正确elisp实现如何?

修改:

我没有看到Seans如何通过简单易读的语法来解释更复杂的替换(我在我的应用程序中需要),所以例如正确(和易于阅读)等同于

(query-replace-regexp "\\([0-9]+\\)\\.Number.\\([0-9]+\\)" "\\,((+ 3 \\#1)).Number.\\,((+ 8 \\#2))")

1 个答案:

答案 0 :(得分:1)

像这样:

(defun Nshift ()
  (interactive)
  (while (search-forward-regexp "\\([0-9]+\\)\\.Number" nil t)
    (replace-match (format "%s.Number" (+ 3 (string-to-number (match-string 1)))))))

编辑添加:

您的扩展示例可以通过以下方式实现:

(defun Nshift ()
  (interactive)
  (while (search-forward-regexp "\\([0-9]+\\)\\.Number\\.\\([0-9]+\\)" nil t)
    (replace-match
     (number-to-string (+ 3 (string-to-number (match-string 1))))
     nil nil nil 1)
    (replace-match
     (number-to-string (+ 8 (string-to-number (match-string 2))))
     nil nil nil 2)))

它实际上比我原来的解决方案更容易,因为我忘了replace-match有一个可选的第五个参数,它导致它只替换一个子表达式,并且不必复制固定文本(“.Number 。“)替换文本。

可以在这里完成一些重构:

(defun increment-match-string (match-index increment)
  (replace-match
   (number-to-string (+ increment (string-to-number (match-string match-index))))
   nil nil nil match-index))

然后Nshift可以这样实现:

(defun Nshift ()
  (interactive)
  (while (search-forward-regexp "\\([0-9]+\\)\\.Number\\.\\([0-9]+\\)" nil t)
    (increment-match-string 1 3)
    (increment-match-string 2 8)))