Emacs:如何在defun中用lisp函数替换-regexp?

Ado*_*obe 8 lisp emacs

例如,我想在括号,(),UPCASE中创建所有文本.以交互方式执行以下操作非常简单:

M-x query-replace-regexp
replace: "(\(.+?\))"
with   : "(\,(upcase \1))"
Run Code Online (Sandbox Code Playgroud)

相反,我想写一个defun会这样做:

(defun upcs ()
  (interactive)
  (goto-char 1)
  (while (search-forward "(\\(.+?\\))" nil t) (replace-match "(\\,(upcase \\1))" t nil)))
Run Code Online (Sandbox Code Playgroud)

但它不起作用!虽然下面的工作(其追加foobar以括号文本):

(defun HOOK ()
  (interactive)
  (goto-char 1)
  (while (search-forward-regexp "(\\(.+?\\))" nil t) (replace-match "(foo \\1 bar)" t nil)))
Run Code Online (Sandbox Code Playgroud)

zev*_*zev 7

卢克的答案几乎完成了这项工作,但并不完全.原始海报希望括号中包含的所有文本都转换为大写,而Luke的代码将代码转换为大写,并删除括号.对正则表达式稍作修改即可提供正确的解决方案:

(defun upcs ()
(interactive)
(goto-char 1)
    (while (search-forward-regexp "\\([^\\)]+\\)" nil t) 
        (replace-match (upcase (match-string 1)) t nil)))
Run Code Online (Sandbox Code Playgroud)


Luk*_*vin 6

首先,你正在使用search-forward你的第一个功能.这需要字符串文字而不是正则表达式.您应该使用search-forward-regexp,就像在第二个功能中一样.

其次,虽然此代码作为替换值有效query-replace-regexp,但我认为您不能将其传递给replace-match:

(\\,(upcase \\1))

您可以search-forward-regexp使用该match-string函数获取找到的匹配值.

最后,我不确定您的搜索正则表达式是否正确.

我认为你需要这些方面的东西:

(defun upcs ()
    (interactive)
    (goto-char 1)
        (while (search-forward-regexp "(\\([^\\)]+\\))" nil t) 
            (replace-match (upcase (match-string 1)) t nil)))
Run Code Online (Sandbox Code Playgroud)


Ado*_*obe 6

所以这解决了问题。

(defun put-in-par (str)
  (concat "(" str ")"))

(defun upcs-luke ()
    (interactive)
    (goto-char 1)
        (while (search-forward-regexp "(\\([^\\)]+\\))" nil t) 
            (replace-match (put-in-par (upcase (match-string 1))) t nil)))
Run Code Online (Sandbox Code Playgroud)

感谢 BillC 和 Luke Girvin 的帮助。