Groups | Search | Server Info | Login | Register
Groups > comp.lang.scheme > #6528
| 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.
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 | Next — Previous in thread | Find similar
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