0

I have this code to find empty strings in a region.

(defun replace-in-region (start end)
  (interactive "r")
  (let ((region-text (buffer-substring start end))
        (temp nil))
    (delete-region start end)
    (setq temp (replace-regexp-in-string "\\_>" "X" region-text))
    (insert temp)))

When I use it on a region it wipes it out, no matter the content of said region, and gives the error "Args out of range: 4, 4".

When I use query-replace-regexp in a region containing:

abcd abcd
abcd 11.11

Been the regexp \_> (note that there is only one backslash) and rep X the resulting region after 4 occurences are replaced is:

abcdX abcdX
abcdX 11.11X

What am I missing here?

1
  • 1
    BTW, the combination of buffer-substring and delete-region has its own function: delete-and-extract-region.
    – legoscia
    Commented May 23, 2016 at 11:23

1 Answer 1

2

It looks like a bug in replace-regexp-in-string.

It first match the regexp in the original string. For example, it finds the end of "abcd". It then picks out the substring that match and, for some reason unknown to me, redo the match on the substring. In this case, the match fails (as it no longer follows a word), but the code that follows it assumes that it succeeded and that the match data has been updated.

Please report this as a bug using M-x report-emacs-bug.

I would suggest that you replace the call to replace-regexp-in-string with a simple loop. In fact, I would recommend that you don't cut out the string and do something like the following:

(defun my-replace-in-region (start end)
  (interactive "r")
  (save-excursion
    (goto-char start)
    (setq end (copy-marker end))
    (while (re-search-forward "\\_>" end t)
      (insert "X")
      ;; Ensure that the regexp doesn't match the newly inserted
      ;; character.
      (forward-char))))

Not the answer you're looking for? Browse other questions tagged or ask your own question.