Reputation: 139
Is there, in Scheme, a good way to replace a substring of a string with another string, the length of which could vary? I am looking for something similar to this:
(replace-all string pattern replacement)
(replace-all "slig slog slag" "g" "ggish")
=> "sliggish sloggish slaggish"
Upvotes: 1
Views: 1979
Reputation: 48775
You can roll your own. It's not very efficient but it will do the work on small strings. (I wouldn't use it on string lengths above a million chars)
Make (prefix? src prefix)
such that i evaluates to #t if the beginning of the list src
is the same as prefix
.
Make (append-reverse rev-head tail)
such that (append-reverse '(1 2 3) '(4 5 6)) ; ==> (3 2 1 4 5 6)
. This could easily be done with foldl
or it's a standard procedure in SRFI-1
Then (replace-all haystack needle replacement)
is quite simple:
(define (replace-all haystack needle replacement)
;; most of the processing works on lists
;; of char, not strings.
(let ((haystack (string->list haystack))
(needle (string->list needle))
(replacement (string->list replacement))
(needle-len (string-length needle)))
(let loop ((haystack haystack) (acc '()))
(cond ((null? haystack)
(list->string (reverse acc)))
((prefix? haystack needle)
(loop (list-tail haystack needle-len)
(reverse-append replacement acc)))
(else
(loop (cdr haystack) (cons (car haystack) acc)))))))
(replace-all "The cat looks like a cat." "cat" "dog")
; ==> "The dog looks like a dog."
Upvotes: 4
Reputation: 236140
Sure, take a look at the documentation of your Scheme interpreter to find a suitable procedure. For instance, in Racket we have string-replace
which works like this:
(string-replace "slig slog slag" "g" "ggish")
=> "sliggish sloggish slaggish"
Upvotes: 3