Re: Optimized string-replace function
Martin Simmons wrote:
> It is wrong to use FORMAT like that, because it will fail if the string
> contains #\~. You can use WRITE-STRING instead.
>
Yet another CL function I had never used. Nice to learn new tricks...
> It is also better to avoid allocating the substrings with SUBSEQ in
> the loop,
> because that will be the main slow-down if there are many matches. Using
> WRITE-STRING with :START/:END and SEARCH with :START2 will allow the
> scan to
> occur directly on STR1.
>
Yes, and the posted version had a bug in it, anyway: dropped a zero from
a SUBSEQ call.
So, here's one with WRITE-STRING:
(defun string-replace4 (text old new)
(let* ((text (string text))
(old (string old))
(new (string new))
(pos (search old text))
(pos2 0)
(len (length old)))
(if (null pos)
text
(with-output-to-string (s)
(loop while pos
do
(write-string text s :start pos2 :end pos)
(write-string new s)
(setq pos2 (+ pos len))
(setq pos (search old text :start2 pos2))
(unless pos
(write-string text s :start pos2)))))))
--