5

这与 Emacs 有关:正则表达式替换以更改大小写

我的另一个问题是我需要编写搜索替换脚本,但该"\,()"解决方案仅在交互式使用时才有效(对我而言)(emacs 24.2.1)。在脚本内部,它给出了错误:“\'在替换文本中使用无效”。

我通常会在需要时将“执行替换”写入某些要加载的文件。类似于:(

执行替换"<\\([^>]+\\)>" "<\\,(downcase \1)>"tt nil 1 nil (point-min) (point-max))

应该可以调用一个函数来生成替换(pg 741 of the emacs lisp manual),但是我尝试了以下的许多变体,但没有运气:

(defun myfun ()
    (downcase (match-string 0)))

(perform-replace "..." (myfun . ()) t t nil)

任何人都可以帮忙吗?

4

2 回答 2

3

像这样的构造\,()只允许在交互式调用中使用query-replace,这就是 Emacs 在你的情况下抱怨的原因。

文档中perform-replace提到您不应该在 elisp 代码中使用它并提出了一个更好的替代方案,我们可以在此基础上构建以下代码:

(while (re-search-forward "<\\([^>]+\\)>" nil t)
  (replace-match (downcase (match-string 0)) t nil))

如果您仍想以交互方式向用户查询替换,perform-replace那么像您所做的那样使用可能是正确的做法。您的代码中有几个不同的问题:

  1. elisp 手册中所述,替换函数必须采用两个参数(您在 cons 单元格中提供的数据和已经进行的替换次数)。

  2. query-replace-regexp如(或elisp 手册)的文档中所述,您需要确保将case-fold-searchorcase-replace设置为 nil,以便案例模式不会转移到替换。

  3. 您需要引用 cons cell (myfun . nil),否则它将被解释为函数调用并过早评估。

这是一个工作版本:

(let ((case-fold-search nil))
  (perform-replace "<\\([^>]+\\)>"
                   `(,(lambda (data count)
                       (downcase (match-string 0))))
                   t t nil))
于 2012-12-04T15:47:02.490 回答
2

C-h f perform-replace说:

Don't use this in your own program unless you want to query and set the mark
just as `query-replace' does.  Instead, write a simple loop like this:

  (while (re-search-forward "foo[ \t]+bar" nil t)
    (replace-match "foobar"))

现在"<\\,(downcase \1)>"需要用构建正确字符串的 Elisp 表达式替换,例如(format "<%s>" (downcase (match-string 1))).

如果您确实需要查询和东西,那么您可能想尝试:C-M-% f\(o\)o RET bar \,(downcase \1) baz RET然后C-x RET RET查看在交互式调用期间构造了哪些参数。

replace.el你会看到发现(如果你点击查看函数的源代码会更好C-h f perform-replace),replacements参数可以采用 (FUNCTION . ARGUMENT) 形式。更具体地说,该代码包含一个注释,提供了一些详细信息:

;; 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.
于 2012-12-04T15:49:48.013 回答