Emacs: Xah Replace Pairs, xah-replace-pairs.el

By Xah Lee. Date: . Last updated: .

xah-replace-pairs.el is a emacs lisp library for doing multi-pair find replace. (the package was named “xfrp_find_replace_pairs.el”)

Here's a sample use:

(require 'xah-replace-pairs)

 [["a" "1"]
  ["b" "2"]
  ["c" "3"]])
;; returns "123def"


Goto paypal.com , send $11 to Xah@XahLee.org , and put in message xah-replace-pairs.el (be sure to include your correct email address. I need that to send it to you.)

Why Multi-Pair Find Replace?

You have a given region in a buffer. You want to do more than one pair of find replace strings. For example:

HTML entities:

The normal way to do find replace in a region is like this:

(defun replace-html-chars-region (begin end)
  "Replace “<” to “&lt;” etc in region."
  (interactive "r")
    (narrow-to-region begin end)

    (goto-char (point-min))
    (while (search-forward "&" nil t) (replace-match "&amp;" nil t))

    (goto-char (point-min))
    (while (search-forward "<" nil t) (replace-match "&lt;" nil t))

    (goto-char (point-min))
    (while (search-forward ">" nil t) (replace-match "&gt;" nil t))))

now you can write it like this:

(require 'xah-replace-pairs)

(defun replace-html-chars-region (begin end)
  (interactive "r")
   begin end
     ["&" "&amp;"]
     ["<" "&lt;"]
     [">" "&gt;"]

Sample Use

Here's sample use.

(defun replace-greek-to-unicode (@begin @end)
  "Replace alpha to α, beta to β etc in current line or selection."
   (if (use-region-p)
       (list (region-beginning) (region-end))
     (list (line-beginning-position) (line-end-position))))
  (let ((case-fold-search nil))
       ["alpha" "α"]
       ["beta" "β"]
       ["gamma" "γ"]
       ["pi" "π"]
       ) 'REPORT 'HILIGHT )))
emacs greek to symbol

Full code at Emacs: Replace Greek Letter Names to Unicode


It implements these functions:

For each function, there's a plain text version and a regex version. They are separate functions so it's simpler for user.

Each function also has a string and region version. The string version works on a given string, the region version works on a region in buffer.

Find Replace Feedback Loop Problem

If find replace pairs is done one after one, then you may end up with a substring that's not in the original input string nor in any of the find replace pairs. For example.

Input string: abcd

replace pairs:


xah-replace-pairs-in-string and xah-replace-pairs-region will not have the feedback loop problem. It guarantees that a replacement is done IF AND ONLY IF the original input string contains a substring in one of your find string.

Real World Implication

Suppose you are working on a HTML tutorial that discusses HTML entities. Suppose the file contains this string:

use “&amp;copy;” for &copy;

The intended display is use “&copy;” for ©.

and you want the HTML source code to be:

use “&amp;copy;” for ©

However, if you are sequentially replacing each entities, the &amp; part will become &, then &copy; becomes just ©, so you got use “©” for © WRONG!


For many examples of using multi-pair find/replace, See: Emacs Lisp Find Replace String-Pairs Commands.