;;;; ;;;; r e g e x p . s t k -- Regular expressions ;;;; ;;;; ;;;; Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI ;;;; ;;;; Permission to use, copy, modify, distribute,and license this ;;;; software and its documentation for any purpose is hereby granted, ;;;; provided that existing copyright notices are retained in all ;;;; copies and that this notice is included verbatim in any ;;;; distributions. No written agreement, license, or royalty fee is ;;;; required for any of the authorized uses. ;;;; This software is provided ``AS IS'' without express or implied ;;;; warranty. ;;;; ;;;; Author: Erick Gallesio [eg@unice.fr] ;;;; Creation date: 9-Nov-1994 13:24 ;;;; Last file update: 3-Sep-1999 19:54 (eg) ;;;; ;;;; Regexp-replace-all bug correction due to Sean Slattery ;;;; (if (symbol-bound? '%init-regexp) ;; Regexp module is in the core interpreter (%init-regexp) ;; Try to load regexp module dynamically (load (string-append "sregexp." *shared-suffix*))) (define (replace-string string ind1 ind2 new) (string-append (substring string 0 ind1) new (substring string ind2 (string-length string)))) (define regexp-replace #f) (define regexp-replace-all #f) (let () ;; Utility function ;; Given a string and a set of substitutions, return the substitued string (define (replace-submodels string subst match) (if (= (length match) 1) ;; There is no sub-model subst ;; There are at least one sub-model to replace (let Loop ((subst subst)) (let ((pos ((string->regexp "\\\\[0-9]") subst))) (if pos ;; At least one \x in the substitution string (let* ((index (+ (caar pos) 1)) (val (string->number (substring subst index (+ index 1))))) (if (>= val (length match)) (error "regexp-replace: cannot match \\~A in model" val) ;; Build a new subst with the current \x remplaced by ;; its value. Iterate for further \x (Loop (replace-string subst (caar pos) (cadar pos) (apply substring string (list-ref match val)))))) ;; No \x in substitution string subst))))) ;; If there is a match, call replace-submodels; otherwise return string unmodified ;; This function takes an iterator function to allow multiple substitution ;; (iterator function = Identity for regexp-replace) (set! regexp-replace (lambda (pat str subst) (let* ((regexp (cond ((regexp? pat) pat) ((string? pat) (string->regexp pat)) (else (error "regexp-replace: Bad pattern '~1'" pat)))) (match (regexp str))) (if match ;; There was a match (replace-string str (caar match) (cadar match) (replace-submodels str subst match)) ;; No match, return the original string str)))) (set! regexp-replace-all (lambda (pat str subst) (letrec ((regexp-replace-all-r (lambda (regexp str subst) (let ((match (regexp str))) (if match (string-append (substring str 0 (caar match)) (replace-submodels str subst match) (regexp-replace-all-r regexp (substring str (cadar match) (string-length str)) subst)) str))))) (let ((regexp (cond ((regexp? pat) pat) ((string? pat) (string->regexp pat)) (else (error "regexp-replace: Bad pattern '~1'" pat))))) (regexp-replace-all-r regexp str subst)))))) (provide "regexp")