[racket] multi-replace function

From: prad (prad at towardsfreedom.com)
Date: Tue Dec 7 01:21:55 EST 2010

i'm trying create a multi-replace function in racket where you can
substitute for patterns in a string with items in a list:

(mult-repl "~A" 
           "this ~A string will experience ~A substitution"
           (list "wonderful" "massive"))
-> "this wonderful string will experience massive substitution"

we've come up with 3 ways so far (the 3rd is my son's) and i have 3
questions (labelled A. B. C.) towards the end of the post. much
appreciation to anyone who responds to this lengthy post.

1. splits string into list of strings on pattern then joins it all up
with the substitutions

(define (rp-pol1 patt ostr lst)
  "splits string into list on pattern and concats items"
  (define (joinup s l1 l2)
    (if (null? l2)
        (string-append s (car l1))
        (joinup (string-append s (car l1) (car l2))
                (cdr l1)
                (cdr l2))))
  (joinup "" (regexp-split patt ostr) lst)
  (display ""))

2. does a straight-forward regex replace within the string

(define (rp-pol2 patt ostr lst)
  "just does regex replace over list"
  (if (null? lst)
      (rp-pol2 patt
              (regexp-replace patt ostr (car lst))
              (cdr lst)))
  (display ""))

3. builds a new string with substitutions and uses an auxiliary get-pos
function to handle situations when there is no more patterns (sorry it
is not coming out too well because of the email wrap)

(define (rp-pol3 patt ostr lst) 
"builds new string substituting along the way" 
 (local ((define patt-leng (string-length patt))
          (define (subs acc beg rpl)
            (let ((patt-sta (get-pos patt ostr beg)))
              (cond ((and patt-sta (null? rpl)) (error "some string
              eh!")) ((not patt-sta) (string-append acc (substring ostr
              beg))) (else (subs (string-append acc (substring ostr beg
                                               (car rpl))
                                (+ patt-sta patt-leng)
                                (cdr rpl)))))))
         (subs "" 0 lst))
  (display ""))

(define (get-pos p s sta)
  (let ((match-result (regexp-match-positions p s sta)))
    (if match-result
        (caar match-result)

i ran time on the these on a 3M file with 3 substitutions without
printing (hence the display "") thinking that #3 would likely be the
fastest and #2 would be the slowest (regex are supposed to be slow?).

however, the results are quite inconclusive. they jump around for all
of them between 113-300 cpu time, mostly being around 170. 
A. is that because i don't have a sufficiently substantial process
B. should any of the above be significantly faster than another?

speed aside, it seems to me that #2 is the easiest to program and
C. so are regex a good thing to use in these situations anyway 
because it's not like there's anything that's going to be thrown at
them that will stress the system out ... or is that a bad attitude?

In friendship,

                                      ... with you on your journey
Towards Freedom
http://www.towardsfreedom.com (website)
Information, Inspiration, Imagination - truly a site for soaring I's

Posted on the users mailing list.