【问题标题】:problem with using replace-regexp in lisp在 lisp 中使用替换正则表达式的问题
【发布时间】:2011-05-26 23:07:50
【问题描述】:

在我的文件中,我有很多 ID="XXX" 实例,我想将第一个实例替换为 ID="0",将第二个实例替换为 ID="1",依此类推。

当我交互使用 regexp-replace 时,我使用ID="[^"]*" 作为搜索字符串,ID="\#" 作为替换字符串,一切都很好。

现在我想把它绑定到一个键上,所以我试着用 lisp 来做,像这样:

(replace-regexp "ID=\"[^\"]*\"" "ID=\"\\#\"")

但是当我尝试评估它时,我得到一个“选择删除的缓冲区”错误。这可能与转义字符有关,但我无法弄清楚。

【问题讨论】:

    标签: regex emacs elisp


    【解决方案1】:

    不幸的是,\# 构造仅在对replace-regexp 的交互式调用中可用。来自documentation

    In interactive calls, the replacement text may contain `\,'
    followed by a Lisp expression used as part of the replacement
    text.  Inside of that expression, `\&' is a string denoting the
    whole match, `\N' a partial match, `\#&' and `\#N' the respective
    numeric values from `string-to-number', and `\#' itself for
    `replace-count', the number of replacements occurred so far.
    

    在文档的末尾,您会看到以下提示:

    This function is usually the wrong thing to use in a Lisp program.
    What you probably want is a loop like this:
      (while (re-search-forward REGEXP nil t)
        (replace-match TO-STRING nil nil))
    which will run faster and will not set the mark or print anything.
    

    这将我们引向这段省略号:

    (save-excursion
      (goto-char (point-min))
      (let ((count 0))
        (while (re-search-forward "ID=\"[^\"]*\"" nil t)
          (replace-match (format "ID=\"%s\"" (setq count (1+ count)))))))
    

    您也可以使用键盘 macro,但我更喜欢 lisp 解决方案。

    【讨论】:

    • 如果你不介意使用cl 包,你可以使用incf 函数来增加计数——这只是生成setq 调用的糖。
    • @seh,是的,我想到了。但我通常会忘记(require 'cl) 并有人指出...
    猜你喜欢
    • 2011-09-07
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多