Elisp: Find Replace Text in Buffer

By Xah Lee. Date: . Last updated: .

Functions for Find Replace in a Region

replace-string-in-region
(replace-string-in-region STRING REPLACEMENT &optional START END)

Replace string in a region. No regex. START default to current cursor position. END default to end of buffer.

return the count of placement, or nil if none.

Comparisons and replacements are done with fixed case.

new in Emacs 28 (Released 2022-04)

🛑 WARNING: if you need to do this again, remember that the END position may have changed.

(replace-string-in-region "some" "thing" )
;; some thing in water
replace-regexp-in-region
(replace-regexp-in-region REGEX REPLACEMENT &optional START END)

Replace Regular Expression in a region. START default to current cursor position. END default to end of buffer.

return the count of placement, or nil if none.

Comparisons and replacements are done with fixed case.

in REPLACEMENT, the following has special meaning:

  • \& → the original matched text.
  • \N nth capture. it is empty string if capture didn't match.
  • \\ means one backslash.

new in Emacs 28 (Released 2022-04)

🛑 WARNING: if you need to do this again, remember that the END position may have changed.

(replace-regexp-in-region "[0-9]+ " "" )
;; i have 5 cats
;; become
;; i have cats

General Method to Do Find Replace Text in Buffer

The general method to do text replacement in current buffer, is via search-forward, re-search-forward etc 〔see Elisp: Search Text Functions〕 , then call replace-match or other function of Match Data. And if you need to restrict the find replace in a region, wrap it with narrow-to-region. 〔see Elisp: Save narrow-to-region

The emacs 28 new functions replace-string-in-region, replace-regexp-in-region are convenient wrapper of this method.

(let ((case-fold-search nil))
  ;; set case-fold-search to t, if you want to ignore case

  (goto-char (point-min))
  (while (search-forward "myStr" nil t)
    (replace-match "myReplaceStr"))

  ;; repeat for other string pairs

  ;; use re-search-forward if you want regex

  )

Find Replace in a Region

;; idiom for multiple string replacement within a region
(save-restriction
  (narrow-to-region pos1 pos2)

  ;; plain text find replace
  (goto-char (point-min))
  (while (search-forward "myStr1" nil t)
    (replace-match "myReplaceStr1"))

  ;; regex find replace
  (goto-char (point-min))
  (while (re-search-forward "someregex" nil t)
    (replace-match "myReplaceStr1"))

  ;; more find replace here

  )

Replace Match

replace-match
(replace-match NEWTEXT &optional FIXEDCASE LITERAL STRING SUBEXP)

Replace the matched pattern of previous text search function call. ( • search-forwardsearch-backwardre-search-forwardre-search-backward )

  • NEWTEXT is replacement string.
  • If FIXEDCASE is true, no case conversion in replacement.
  • If LITERAL is true, no backslash interpretation.

in replace string NEWTEXT, backslash has the following special meaning, unless LITERAL is true:

  • \& → whole matched text.
  • \N → nth captured group.
  • \\ → literal backslash.

🛑 WARNING: each backslash should be double in string.

(let ((case-fold-search nil))
  (re-search-forward "x\\([0-9]+\\)" nil t)
  (replace-match "ID \\1"))

;; x803
;; becomes
;; ID 803

Case Sensitivity in Replacement

To control letter case of the replacement, use the optional arguments in replace-match function.

(replace-match NEWTEXT &optional FIXEDCASE LITERAL STRING SUBEXP)

Use t for FIXEDCASE.

By default, the letter case used in replacement is smart. If the found text is First-cap or ALLCAPS, the replacement is accordingly.

Match Data

the begin/end positions of match, or capture, are stored in match-data.

Elisp, Regex in Lisp Code

Elisp, text processing functions