Lisp HUG Maillist Archive

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)))))))



-- 


Updated at: 2020-12-10 08:39 UTC