It is clear to me how to programmatically replace all instances of regex in a buffer with some text, something like (pardon my naive code):
(defun my/regex-global-replace (regex subst-text)
"Globally replace `regex' with `subst-text' in current buffer"
(goto-char (point-min))
(while (re-search-forward regex nil t)
(replace-match subst-text)))
But I can't figure it out how to do a similar global replace when using capture groups and sub-matches.
I am aware of this answer and the Cookbook entry, but it does not help me much, since it is not clear how I could use the sub-matches to replace text globally.
How could one write a broader version of the code above, so that it deals with sub-matches, something like:
(defun my/regex-global-replace (regex1 regex2)
"Replace `regex1' with `regex2' in a buffer."
(goto-char (point-min))
(while (re-search-forward regex1 nil t)
(replace-match regex2)))
Where regex1 may contain a certain number of capture groups, like,
(setq regex1 "some text \\([[:digit:]]+\\)")
and regex2 a related sub-match, the equivalent of PCRE's $1
or \1
?
Example
As an example, say I have a buffer with content,
Some text 123
Some more text 456
I would like to programmatically run a global search-and-replace that would, as example, change text but keep the numbers,
Changed text, keep digits 123
Changed text, keep digits 456
In some other languages (Perl comes to mind), I would create a search regex with a capture group, and a replace expression using the sub-matches, something like
s/(\w+\s+)+(\d+)\n/Changed text, keep digits \2\n/gim
\\2
in the replacement text. It it as simple as that. Note the escaping that is needed within strings to get a single character\
in the resulting string.\2
would just insert the character with octal code 2.(while (re-search-forward "\\([[:alpha:][:space:]]\\)+\\([0-9]+\\)" nil t) (replace-match "Changed text, keep digits \\2\n"))
. Note, that you have to be careful with\\sw
since this also matches digits. Therefore the above example is written with the character class[:alpha:]
. The space could also be written as\\s-
.