从Emacs 28.1 发布了, tag 已经打了。继续讨论:
我正在通过看 28.1 的 NEWS 文件学习新变化,更新下 elisp-demos 中的例子。遇到一个新函数 replace-regexp-in-region
,我试了下,对它的行为有疑问:
(replace-regexp-in-string "[0-9]" "XX" "#1 #2 #3")
;; => "#XX #XX #XX"
(with-temp-buffer
(insert "#1 #2 #3")
(replace-regexp-in-region "[0-9]" "XX" (point-min))
(buffer-string))
;; => "#XX #XX #3"
我看过了 replace-regexp-in-region
的实现,知道它受替换 REPLACEMENT
的长度的影响,长度比原来的长,甚至搜索范围溢出而报错,现在的这种还有多大用吗?就是故意如此设计的吗?
(with-temp-buffer
(insert "#1 #2 #3")
(replace-regexp-in-region "[0-9]" "XXX" (point-min))
(buffer-string))
;; -> (error "Invalid search bound (wrong side of point)")
replace-regexp-in-region
用起来挺奇怪的:
(with-temp-buffer
(insert "#1 #2 #3 a")
(replace-regexp-in-region "[0-9]" "XX" (point-min))
(buffer-string))
;; → replace-regexp-in-region: Invalid search bound (wrong side of point)
还是习惯这样:
(with-temp-buffer
(insert "#1 #2 #3")
(goto-char (point-min))
(while (re-search-forward "[0-9]" nil t)
(replace-match "XX" nil nil ))
(buffer-string))
;; → "#XX #XX #XX"
如果改为从尾部开始替换就不会出错了:
- (goto-char start)
- (while (re-search-forward regexp end t)
+ (goto-char end)
+ (while (re-search-backward regexp start t)
(with-temp-buffer
(insert "#1 #2 #3 a")
(replace-regexp-in-region "[0-9]" "XX" (point-min))
(buffer-string))
;; => "#XX #XX #XX a"