Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

problem with using replace-regexp in lisp

Tags:

regex

emacs

elisp

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.

like image 593
Bwmat Avatar asked Dec 08 '25 20:12

Bwmat


1 Answers

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.

like image 51
Trey Jackson Avatar answered Dec 11 '25 12:12

Trey Jackson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!