前一段时间@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))")
答案 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)))