Add new functions to replace strings/regexp in a region
* doc/lispref/searching.texi (Search and Replace): Document them. * lisp/subr.el (replace-string-in-region) (replace-regexp-in-region): New functions. * lisp/emacs-lisp/shortdoc.el (regexp, buffer): Mention them.
This commit is contained in:
parent
42be416578
commit
751f1707f0
5 changed files with 139 additions and 6 deletions
|
@ -2540,9 +2540,9 @@ associated with it still exists.
|
|||
@cindex replacement after search
|
||||
@cindex searching and replacing
|
||||
|
||||
If you want to find all matches for a regexp in part of the buffer,
|
||||
and replace them, the best way is to write an explicit loop using
|
||||
@code{re-search-forward} and @code{replace-match}, like this:
|
||||
If you want to find all matches for a regexp in part of the buffer
|
||||
and replace them, the most flexible way is to write an explicit loop
|
||||
using @code{re-search-forward} and @code{replace-match}, like this:
|
||||
|
||||
@example
|
||||
(while (re-search-forward "foo[ \t]+bar" nil t)
|
||||
|
@ -2553,9 +2553,23 @@ and replace them, the best way is to write an explicit loop using
|
|||
@xref{Replacing Match,, Replacing the Text that Matched}, for a
|
||||
description of @code{replace-match}.
|
||||
|
||||
However, replacing matches in a string is more complex, especially
|
||||
if you want to do it efficiently. So Emacs provides two functions to do
|
||||
this.
|
||||
@findex replace-regexp-in-region
|
||||
If it's more convenient, you can also use the
|
||||
@code{replace-regexp-in-region}, which does something similar to the
|
||||
loop above, but is optionally delimited to a specific region (and
|
||||
doesn't change point). Furthermore, it does the searches
|
||||
case-sensitively, and performs the replacements without changing case
|
||||
in the replacement.
|
||||
|
||||
@example
|
||||
(replace-regexp-in-region "foo[ \t]+bar" "foobar")
|
||||
@end example
|
||||
|
||||
@findex replace-string-in-region
|
||||
There's also @code{replace-string-in-region}, which works along the
|
||||
same lines, but searches for literal strings instead.
|
||||
|
||||
Emacs also has special functions for replacing matches in a string.
|
||||
|
||||
@defun replace-regexp-in-string regexp rep string &optional fixedcase literal subexp start
|
||||
This function copies @var{string} and searches it for matches for
|
||||
|
|
6
etc/NEWS
6
etc/NEWS
|
@ -2443,6 +2443,12 @@ images are marked.
|
|||
|
||||
** Miscellaneous
|
||||
|
||||
+++
|
||||
*** New function 'replace-regexp-in-region'.
|
||||
|
||||
+++
|
||||
*** New function 'replace-string-in-region'.
|
||||
|
||||
---
|
||||
*** New function 'mail-header-parse-addresses-lax'.
|
||||
This takes a comma-separated string and returns a list of mail/name
|
||||
|
|
|
@ -700,6 +700,8 @@ There can be any number of :example/:result elements."
|
|||
(match-substitute-replacement
|
||||
:no-eval (match-substitute-replacement "new")
|
||||
:eg-result "new")
|
||||
(replace-regexp-in-region
|
||||
:no-value (replace-regexp-in-region "[0-9]+" "Num \\&"))
|
||||
"Utilities"
|
||||
(regexp-quote
|
||||
:eval (regexp-quote "foo.*bar"))
|
||||
|
@ -894,6 +896,10 @@ There can be any number of :example/:result elements."
|
|||
:no-value (erase-buffer))
|
||||
(insert
|
||||
:no-value (insert "This string will be inserted in the buffer\n"))
|
||||
(subst-char-in-region
|
||||
:no-eval "(subst-char-in-region (point-min) (point-max) ?+ ?-)")
|
||||
(replace-string-in-region
|
||||
:no-value (replace-string-in-region "foo" "bar"))
|
||||
"Locking"
|
||||
(lock-buffer
|
||||
:no-value (lock-buffer "/tmp/foo"))
|
||||
|
|
61
lisp/subr.el
61
lisp/subr.el
|
@ -3859,6 +3859,67 @@ Point in BUFFER will be placed after the inserted text."
|
|||
(with-current-buffer buffer
|
||||
(insert-buffer-substring current start end))))
|
||||
|
||||
(defun replace-string-in-region (string replacement &optional start end)
|
||||
"Replace STRING with REPLACEMENT in the region from START to END.
|
||||
The number of replaced occurrences are returned, or nil if STRING
|
||||
doesn't exist in the region.
|
||||
|
||||
If START is nil, use the current point. If END is nil, use `point-max'.
|
||||
|
||||
Comparisons and replacements are done with fixed case."
|
||||
(if start
|
||||
(when (< start (point-min))
|
||||
(error "Start before start of buffer"))
|
||||
(setq start (point)))
|
||||
(if end
|
||||
(when (> end (point-max))
|
||||
(error "End after end of buffer"))
|
||||
(setq end (point-max)))
|
||||
(save-excursion
|
||||
(let ((matches 0)
|
||||
(case-fold-search nil))
|
||||
(goto-char start)
|
||||
(while (search-forward string end t)
|
||||
(delete-region (match-beginning 0) (match-end 0))
|
||||
(insert replacement)
|
||||
(setq matches (1+ matches)))
|
||||
(and (not (zerop matches))
|
||||
matches))))
|
||||
|
||||
(defun replace-regexp-in-region (regexp replacement &optional start end)
|
||||
"Replace REGEXP with REPLACEMENT in the region from START to END.
|
||||
The number of replaced occurrences are returned, or nil if REGEXP
|
||||
doesn't exist in the region.
|
||||
|
||||
If START is nil, use the current point. If END is nil, use `point-max'.
|
||||
|
||||
Comparisons and replacements are done with fixed case.
|
||||
|
||||
REPLACEMENT can use the following special elements:
|
||||
|
||||
`\\&' in NEWTEXT means substitute original matched text.
|
||||
`\\N' means substitute what matched the Nth `\\(...\\)'.
|
||||
If Nth parens didn't match, substitute nothing.
|
||||
`\\\\' means insert one `\\'.
|
||||
`\\?' is treated literally."
|
||||
(if start
|
||||
(when (< start (point-min))
|
||||
(error "Start before start of buffer"))
|
||||
(setq start (point)))
|
||||
(if end
|
||||
(when (> end (point-max))
|
||||
(error "End after end of buffer"))
|
||||
(setq end (point-max)))
|
||||
(save-excursion
|
||||
(let ((matches 0)
|
||||
(case-fold-search nil))
|
||||
(goto-char start)
|
||||
(while (re-search-forward regexp end t)
|
||||
(replace-match replacement t)
|
||||
(setq matches (1+ matches)))
|
||||
(and (not (zerop matches))
|
||||
matches))))
|
||||
|
||||
(defun yank-handle-font-lock-face-property (face start end)
|
||||
"If `font-lock-defaults' is nil, apply FACE as a `face' property.
|
||||
START and END denote the start and end of the text to act on.
|
||||
|
|
|
@ -694,5 +694,51 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350."
|
|||
(should-not (buffer-local-boundp 'test-not-boundp buf))
|
||||
(should (buffer-local-boundp 'test-global-boundp buf))))
|
||||
|
||||
(ert-deftest test-replace-string-in-region ()
|
||||
(with-temp-buffer
|
||||
(insert "foo bar zot foobar")
|
||||
(should (= (replace-string-in-region "foo" "new" (point-min) (point-max))
|
||||
2))
|
||||
(should (equal (buffer-string) "new bar zot newbar")))
|
||||
|
||||
(with-temp-buffer
|
||||
(insert "foo bar zot foobar")
|
||||
(should (= (replace-string-in-region "foo" "new" (point-min) 14)
|
||||
1))
|
||||
(should (equal (buffer-string) "new bar zot foobar")))
|
||||
|
||||
(with-temp-buffer
|
||||
(insert "foo bar zot foobar")
|
||||
(should-error (replace-string-in-region "foo" "new" (point-min) 30)))
|
||||
|
||||
(with-temp-buffer
|
||||
(insert "Foo bar zot foobar")
|
||||
(should (= (replace-string-in-region "Foo" "new" (point-min))
|
||||
1))
|
||||
(should (equal (buffer-string) "new bar zot foobar"))))
|
||||
|
||||
(ert-deftest test-replace-regexp-in-region ()
|
||||
(with-temp-buffer
|
||||
(insert "foo bar zot foobar")
|
||||
(should (= (replace-regexp-in-region "fo+" "new" (point-min) (point-max))
|
||||
2))
|
||||
(should (equal (buffer-string) "new bar zot newbar")))
|
||||
|
||||
(with-temp-buffer
|
||||
(insert "foo bar zot foobar")
|
||||
(should (= (replace-regexp-in-region "fo+" "new" (point-min) 14)
|
||||
1))
|
||||
(should (equal (buffer-string) "new bar zot foobar")))
|
||||
|
||||
(with-temp-buffer
|
||||
(insert "foo bar zot foobar")
|
||||
(should-error (replace-regexp-in-region "fo+" "new" (point-min) 30)))
|
||||
|
||||
(with-temp-buffer
|
||||
(insert "Foo bar zot foobar")
|
||||
(should (= (replace-regexp-in-region "Fo+" "new" (point-min))
|
||||
1))
|
||||
(should (equal (buffer-string) "new bar zot foobar"))))
|
||||
|
||||
(provide 'subr-tests)
|
||||
;;; subr-tests.el ends here
|
||||
|
|
Loading…
Add table
Reference in a new issue