我正在寻找只使用文字字符串,没有正则表达式的等效replace-regexp-in-string
。
(replace-regexp-in-string "." "bar" "foo.buzz") => "barbarbarbarbarbarbarbar"
但我想要
(replace-in-string "." "bar" "foo.buzz") => "foobarbuzz"
我尝试了各种replace-*
函数,但无法弄明白。
修改
作为对精心设计的答案的回报,我决定对它们进行基准测试(是的,我知道所有基准测试都是错误的,但它仍然很有趣)。
benchmark-run
的输出为(time, # garbage collections, GC time)
:
(benchmark-run 10000
(replace-regexp-in-string "." "bar" "foo.buzz"))
=> (0.5530160000000001 7 0.4121459999999999)
(benchmark-run 10000
(haxe-replace-string "." "bar" "foo.buzz"))
=> (5.301392 68 3.851943000000009)
(benchmark-run 10000
(replace-string-in-string "." "bar" "foo.buzz"))
=> (1.429293 5 0.29774799999999857)
用引用的regexp获胜替换-regexp-in-string。临时缓冲区做得非常好。
修改2
现在有了汇编!不得不再做10倍的迭代:
(benchmark-run 100000
(haxe-replace-string "." "bar" "foo.buzz"))
=> (0.8736970000000001 14 0.47306700000000035)
(benchmark-run 100000
(replace-in-string "." "bar" "foo.buzz"))
=> (1.25983 29 0.9721819999999983)
(benchmark-run 100000
(replace-string-in-string "." "bar" "foo.buzz"))
=> (11.877136 86 3.1208540000000013)
haxe-replace-string看起来不错
答案 0 :(得分:20)
试试这个:
(defun replace-in-string (what with in)
(replace-regexp-in-string (regexp-quote what) with in nil 'literal))
答案 1 :(得分:11)
(s-replace "." "bar" "foo.buzz") ;; => "foobarbuzz"
如果您使用Elisp中的字符串,我建议您从Emacs包管理器安装s.el
。
答案 2 :(得分:5)
Emacs 28.1(在撰写本文时仍在开发中)将此作为标准提供:
** New function 'string-replace'.
This function works along the line of 'replace-regexp-in-string', but
matching on strings instead of regexps, and does not change the global
match state.
(string-replace FROMSTRING TOSTRING INSTRING)
Replace FROMSTRING with TOSTRING in INSTRING each time it occurs.
(string-replace ".*" "BAR" "foo.*bar.*baz")
⇒ "fooBARbarBARbaz"
答案 3 :(得分:4)
我不希望这更快:
(defun haxe-replace-string (string string-a string-b)
"Because there's no function in eLisp to do this."
(loop for i from 0 upto
(- (length string) (length string-a))
for c = (aref string i)
with alen = (length string-a)
with result = nil
with last = 0
do (loop for j from i below (+ i alen)
do (unless
(char-equal
(aref string-a (- j i))
(aref string j))
(return))
finally
(setq result
(cons (substring string last (- j alen)) result)
i (1- j) last j))
finally
(return
(if result
(mapconcat
#'identity
(reverse (cons (substring string last) result)) string-b)
string))))
Becasue replace-regexp-in-string
是一个原生函数,但你永远不会知道......不管怎样,我之前因某种原因写过这个,所以,如果你喜欢比较性能 - 欢迎你试试:)
另一个想法,使用临时缓冲区:
(defun replace-string-in-string (what with in)
(with-temp-buffer
(insert in)
(beginning-of-buffer)
(while (search-forward what nil t)
(replace-match with nil t))
(buffer-string)))
答案 4 :(得分:2)
s-replace
很好,但是说您想在加载过程中尽早使用替换字符串功能,并且还没有加载或s.el
需要所有这些。好吧,这是s-replace
中s.el
的定义。如您所见,它没有依赖性,因此您可以使用它而无需其余s.el
:
(defun s-replace (old new s)
"Replaces OLD with NEW in S."
(declare (pure t) (side-effect-free t))
(replace-regexp-in-string (regexp-quote old) new s t t))