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

时间:2011-06-18 12:09:39

标签: emacs lisp

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

M-x query-replace-regexp
replace: "(\(.+?\))"
with   : "(\,(upcase \1))"

相反,我想写一个defun来做那个:

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

但它不起作用!虽然以下工作(它将foobar附加到带括号的文本中):

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

5 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分: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)))

答案 2 :(得分:3)

所以这解决了这个问题。

(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)))

感谢BillC和Luke Girvin的帮助。

答案 3 :(得分:1)

这非常有用,谢谢大家。

为了在网络上放置更多的例子,我从这里开始:

(replace-regexp "\([\%\)\”\"]\..?\)[0-9]+" "\1")

(这不起作用,但使用了在交互模式下工作的正则表达式)

到此:

(while (re-search-forward "\\([\\%\\\"\\”]\\)\\.?[0-9]+" nil t)
    (replace-match (match-string 1) t nil))

我在内部引号前需要三个反斜杠。

答案 4 :(得分:0)

基于正则表达式的交互式替换函数无法更改大小写,但默认情况下可以正常工作:case-replace 变量需要设置为 nil(默认值:t)。然后交互式替换将与 ,(upcase \1) 和朋友一起正常工作。

参考:参见 emacs-berlin 邮件列表的讨论:https://mailb.org/pipermail/emacs-berlin/2021/000840.html