Emacs Lisp: Call Function in Replacement String
This page shows you how to use a elisp function in your regex replacement.
For example, replace “_” to space in matched pattern.
In the replace string prompt, give
\,(function_name), where function_name is your elisp function. The function's return value will be used as the replacement string.
Following are details.
Suppose you have thousands of links like this:
you want to change the link text so that _ is replaced by space, like this:
<a href="…/this_and_that">this and that</a>
First, you need to use regex find / replace to match the links. Then, you need a function to to transform the matched pattern.
Call Function in Replacement String
You can use a function as your replacement string. (new in emacs 22, released in )
In the replace string prompt, give
\,(function_name), where function_name is your elisp function.
The function needs no argument. Its return value is used as the replacement string.
The task here is to write the replacement function.
Here's our function sketch:
(defun ff () "temp function. Returns a string based on current regex match." ; 1. get the matched text ; 2. transform the matched text ; 3. returns the transformed text )
How do we actually get the matched text? Here's the solution:
(defun ff () "return matched text with underscore replaced by space." (replace-regexp-in-string "_" " " (match-string 1)) )
To make emacs aware of
ff, select the whole definition, then call
〔►see How to Evaluate Emacs Lisp Code〕
(match-string 1) gives you the first captured string. (“1” is for 1st captured pattern, “2” for 2nd captured pattern. “0” is the entire match.).
replace-regexp-in-string is used to transform the text.
So, with this function written, we can call
query-replace-regexp, then give this pattern:
And the replacement expression would be:
and we are all done.
To save and close all changed files, call
ibuffer and type 【* u S D】. For detail, see Emacs: List Buffers.
You can use this technique to do find replace on all files in a dir. See: Emacs: Find Replace Text in Directory.
Replacement Function Template
Here's a example where i need to find all Wikipedia links and change the link text to use space instead of _.
(defun wikipedia-link-replacement () "Returns a canonical form of Wikipedia link from a regex match. The regex to be used for this function is: <a href=\"http://\\(..\\)\\.wikipedia.org/wiki/\\([^\"]+\\)\">\\(\\([-.A-Za-z0-9]+_\\)+[-.A-Za-z0-9]+ ?\\)</a> To use this function, call `query-replace-regexp', then in the replacement prompt give: \\,(wikipedia-link-replacement) " (let (langCode articlePath linkText linkText2 returnText) (setq langCode (match-string 1)) (setq articlePath (match-string 2)) (setq linkText (match-string 3)) (setq linkText2 (replace-regexp-in-string "_" " " articlePath)) (setq returnText (concat "<a href=\"http://" langCode ".wikipedia.org/wiki/" articlePath "\">" linkText2 "</a>" )) returnText ) )
Example: Replace Emacs Manual Links
Here's another example of batch find replace using a function for replacement.
I need to find all text of the form:
(info "(emacs) Option Index")
and change it into this form:
<a href="../emacs_manual/Option-Index.html">(info "(emacs) Option Index")</a>
Here's the regex i use:
(info "(emacs) \([^"]+?\)")
Here's the replacement code:
Here's the elisp code:
(defun ff () "temp" (interactive) (let (matchedText url replaceText anchorText) (setq matchedText (match-string 1 ) ) (setq replaceText (replace-regexp-in-string " " "-" matchedText)) (setq url (concat "../emacs_manual/" replaceText ".html" ) ) (setq anchorText (concat "(info \"(emacs) " matchedText "\")" ) ) (concat "<a href=\"" url "\">" anchorText "</a>") ))
Here are more examples of using a function as replacement string.
- Emacs Lisp: Add “alt” Attribute to Image Tags
- Emacs Lisp: Replace String Based on File Name
- Emacs Lisp: Replacing HTML Entities with Unicode Characters
- Emacs: Find Replace on Multiple Files by Function: Add Unicode Name in HTML
or, buy something from Best Keyboard for Emacs