[racket] regexp-replace* with input-port ==> Re: multi-replace function
On Tue, Dec 7, 2010 at 12:25 AM, Eli Barzilay <eli at barzilay.org> wrote:
>
> Actually, there's a problem -- there is already an optional argument
> for the prefix, and if an output port is added, it should be added
> before that for consistency but that will be incompatible.
That's unfortunate. Looking at v4.2.5 I did not see the input-prefix param,
so that's probably added in v5.0. I guess it's either be a new name
(something like regexp-replace*/out and regexp-replace/out) or added after
the prefix.
I did a quick proof of concept against 4.2.5 (which doesn't have the
inconsistency of input-prefix), and it works AFAICT. Of course it's better
if this is implemented in the same layer as other regexp functions.
(define (insert-spec->callback spec)
(define (make-substitution matched)
(lambda (m . rest)
(cond ((bytes=? m #"\\&") #"&")
((bytes=? m #"\\\\") #"\\")
((bytes=? m #"&") (car matched))
((= 2 (length rest))
(list-ref matched (string->number (bytes->string/utf-8 (cadr
rest)))))
(else #""))))
(lambda (matched . parts)
(regexp-replace* (byte-pregexp #"(\\&|\\\\([0-9]+))")
spec
(make-substitution (cons matched parts)))))
(define (regexp-replace*/out pat in insert (out #f)) ;; what does #f mean?
(define (helper insert)
(let loop ((matched (regexp-match pat in 0 #f out)))
(unless (not matched)
(display (apply insert matched) out)
(loop (regexp-match pat in 0 #f out)))))
(if (input-port? in)
(if (output-port? out)
(helper (if (procedure? insert)
insert
(insert-spec->callback insert)))
(regexp-replace* pat (port->bytes in) insert))
(regexp-replace* pat in insert)))
(define (regexp-replace/out pat in insert (out #f))
(define (helper insert)
(let ((matched (regexp-match pat in 0 #f out)))
(unless (not matched)
(display (apply insert matched) out)
(copy-port in out))))
(if (input-port? in)
(if (output-port? out)
(helper (if (procedure? insert)
insert
(insert-spec->callback insert)))
(regexp-replace pat (port->bytes in) insert))
(regexp-replace pat in insert)))
> (regexp-replace*/out #px"[0-9]+" (open-input-string "1929,1939,1949,1959")
"+\\0" (current-output-port))
+1929,+1939,+1949,+1959
Cheers,
yc
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20101207/1d355f68/attachment.html>