Groups | Search | Server Info | Login | Register


Groups > comp.lang.scheme > #6528

Re: Substring replacement

From "B. Pym" <Nobody447095@here-nor-there.org>
Newsgroups comp.lang.lisp, comp.lang.scheme
Subject Re: Substring replacement
Date 2025-07-27 23:00 +0000
Organization A noiseless patient Spider
Message-ID <1066b2u$1vk57$1@dont-email.me> (permalink)
References <10634qk$1h1eq$1@dont-email.me>

Cross-posted to 2 groups.

Show all headers | View raw


B. Pym wrote:

> fireblade wrote:
> 
> > Any nice  way of replacing substrings, i'm currently using below
> > it works but it's discusting :
> > (defun substring-replace (new old text )
> >   (let ((res "") (now 0)
> >         (old-length (length old))
> >         (text-length (length text)))
> >    (loop
> >      (if (> (+ now old-length) text-length)
> >          (progn
> >            (if (< now text-length)
> >                (setq res
> >                  (concatenate 'string res
> >                   (subseq text now))))
> >           (return res))
> >          (if (string= old
> >               (subseq text now (+ now old-length)))
> >              (progn
> >                (setq res
> >                  (concatenate 'string res new))
> >                (incf now old-length))
> >              (progn
> >                (setq res
> >                  (concatenate 'string res
> >                   (subseq text now (1+ now))))
> >                (incf now)))))))
> 
> Gauche Scheme
> 
> (use srfi-13)  ;; String functions.
> 
> (define (gsub old new text :optional (start 0) (accum '()))
>   (let1 p (string-contains text old start)
>     (if p
>       (gsub old new text
>         (+ p (string-length old))
>         (cons* new (string-copy text start p) accum))
>       (string-concatenate
>         (reverse (cons (string-copy text start) accum))))))
> 
> If the function "string-contains" isn't available,
> this can be used.
> 
> (define (string-contains text str :optional (start 0))
>   (let1 len-str (string-length str)
>     (do ((i start (+ i 1))
>          (end (- (string-length text) len-str))
>          (found #f
>            (if (string= str (substring text i (+ i len-str)))
>              i #f)))
>       ((or found (> i end)) found))))

As an exercise, I wrote a version using a record (structure).

(use gauche.record)
(define-record-type ssub #t #t
  text old new
  (start)
  (accum)
  (result))

(use srfi-13)  ;; String functions.

To access the fields, I used "~", which in Gauche Scheme
is the "universal accessor".

(define (process-ssub ss)
  (unless (~ ss 'result)
    (let ((text (~ ss 'text))
          (old (~ ss 'old)))
      (if (>= (~ ss 'start) (string-length text))
        (set! (~ ss 'result) (string-concatenate-reverse (~ ss 'accum)))
        (let1 found (string-contains text old (~ ss 'start))
          (if found
            (begin
              (push! (~ ss 'accum)
                (substring text (~ ss 'start) found))
              (push! (~ ss 'accum) (~ ss 'new))
              (set! (~ ss 'start) (+ found (string-length old))))
            (begin
              (push! (~ ss 'accum)
                (string-copy text (~ ss 'start)))
              (set! (~ ss 'start) +inf.0))))))))

(define (gsub old new text)
  (let1 ss (make-ssub text old new 0 '() #f)
    (until (~ ss 'result)  (process-ssub ss))
    (~ ss 'result)))

(gsub "oo" "o" "Too moove the furniture, he droove a truck.")
  ===>
"To move the furniture, he drove a truck."


-- 
[T]he problem is that lispniks are as cultish as any other devout group and
basically fall down frothing at the mouth if they see [heterodoxy].
  --- Kenny Tilton
The good news is, it's not Lisp that sucks, but Common Lisp. --- Paul Graham

Back to comp.lang.scheme | Previous | NextPrevious in thread | Find similar


Thread

re: Substring replacement "B. Pym" <Nobody447095@here-nor-there.org> - 2025-07-26 17:55 +0000
  Re: Substring replacement "B. Pym" <Nobody447095@here-nor-there.org> - 2025-07-27 23:00 +0000

csiph-web