从Emacs的第22版开始,我们可以使用\,(function)
来操作(部分)正则表达式搜索结果,然后再替换它。但是 - 这经常被提及,但仍然是事实 - 我们只能以标准的交互方式使用这种结构。 (互动式:按C-M-%
或使用query-replace-regexp
致电M-x
。)
举个例子:
如果我们有
想要
我们可以使用:
M-x query-replace-regexp <return>
\[\([A-Za-z-]+\)\([^0-9]*\) \([0-9]\{4\}\)\]
[\1\2 \\function{\,(downcase \1)\3}{\3}]
完成它。所以这可以很容易地完成。
在我自己的defun中,我只能通过替换而不自由修改匹配来使用查询,或修改准备好的替换字符串而不进行任何查询。我看到的唯一方法是以这种方式序列化它:
(defun form-to-function ()
(interactive)
(goto-char (point-min))
(while (query-replace-regexp
"\\[\\([A-Za-z-]+\\)\\([^0-9]*\\) \\([0-9]\\{4\\}\\)\\]"
"[\\1\\2 \\\\function{\\1\\3}{\\3}]" ))
(goto-char (point-min))
(while (search-forward-regexp "\\([a-z0-9]\\)" nil t)
(replace-match (downcase (match-string 1)) t nil)
)
)
对我而言查询很重要,因为我无法确定缓冲区为我提供了什么(=我无法确定,作者使用了这种字符串总是以同样的方式)。
我想使用elisp函数,因为它不是唯一的重复替换(并且不仅是一个缓冲区(我知道dired-do-query-replace-regexp
但我更喜欢使用replace-defuns缓冲区工作))
起初我以为我只会遗漏query-replace-match
而不是replace-match
。但我担心,我也错过了重新排列query-replace-regexp
字符串的简单灵活方式。
所以我想,我需要一个\,
用于defun。我真的很想知道,如果我是唯一一个错过这个功能的人。
答案 0 :(得分:2)
如果你想让你的rsearch&amp; replace提示用户,这意味着你希望它是交互式的,所以调用query-replace-regexp
是完全可以的(即使字节编译器会告诉你这是为了仅限交互式使用)。如果警告困扰您,您可以将电话打包在with-no-warnings
或致电perform-replace
。
perform-replace
的文档字符串遗憾地没有(或者说“直到今天”没有“说明replacements
参数的格式是什么,但你可以在函数的代码中看到它:
;; REPLACEMENTS is either a string, a list of strings, or a cons cell
;; containing a function and its first argument. The function is
;; called to generate each replacement like this:
;; (funcall (car replacements) (cdr replacements) replace-count)
;; It must return a string.
答案 1 :(得分:1)
query-replace-function
不仅可以将替换作为字符串处理,还可以作为包含操作元素的列表处理。使用concat
档案构建各种元素的字符串。
因此,在插入替换之前想要通过函数操纵搜索匹配的人也可以在defun中使用query-replace-regexp
。
(defun form-to-function ()
(interactive)
(goto-char (point-min))
(query-replace-regexp
"\\[\\([A-Za-z-]+\\)\\([^0-9]*\\) \\([0-9]\\{4\\}\\)\\]"
(quote (replace-eval-replacement concat "[\\1\\2 \\\\function{"
(replace-quote (downcase (match-string 1))) "\\3}{\\3}]")) nil ))
match-string 1
返回regexp-search的第一个表达式。
`replace-quote'帮助我们双击以下表达式。
concat
从以下元素中形成一个字符串。
和
replace-eval-replacement
未记录在案。为什么它在这里使用,是因为emacs似乎在内部使用它,同时执行第一个»交互«query-replace-regexp
调用。至少是通过向repeat-complex-command
询问emacs来给出的。
我在repeat-complex-command
的源代码中搜索答案时遇到query-replace-regexp
(绑定到[C-x M-:]。)。
因此,通过执行标准搜索和替换方法可以很容易地创建defunved,如第一次成功按[Cx M-:]导致已经生成Lisp的命令,可以复制和粘贴在defun。
perform-replace
)正如Stefan所说,可以使用perform-replace
来避免使用query-replace-regexp
。
这样的功能可能是:
(defun form-to-function ()
(interactive)
(goto-char (point-min))
(while (perform-replace
"\\[\\([A-Za-z-]+\\)\\([^0-9]*\\) \\([0-9]\\{4\\}\\)\\]"
(quote (replace-eval-replacement concat "[\\1\\2 \\\\function{"
(replace-quote (downcase (match-string 1))) "\\3}{\\3}]"))
t t nil)))
第一个布尔值(t)是查询标志,第二个是正则表达式开关。所以它也很完美,但它没有帮助找到替换表达式,就像使用\,
一样简单。