3

in my file, I have many instances of ID="XXX", and I want to replace the first one with ID="0", the second one with ID="1", and so on.

When I use regexp-replace interactively, I use ID="[^"]*" as the search string, and ID="\#" as the replacement string, and all is well.

now I want to bind this to a key, so I tried to do it in lisp, like so:

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

but when I try to evaluate it, I get a 'selecting deleted buffer' error. It's probably something to do with escape characters, but I can't figure it out.

1 Answer 1

9

Unfortunately, the \# construct is only available in the interactive call to replace-regexp. From the 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.

And at the end of the documentation you'll see this hint:

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.

Which then leads us to this bit of elisp:

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

You could also use a keyboard macro, but I prefer the lisp solution.

Sign up to request clarification or add additional context in comments.

2 Comments

If you don't mind using the cl package, you could use the incf function to bump the count -- which is just sugar to generate the setq call you have there.
@seh, Yah, I thought of that. But I usually forget the (require 'cl) and someone points it out...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.