(regexp-quote): [ and | must be quoted. Quote ( ) { + ?
authorKevin Ryde <user42@zip.com.au>
Fri, 27 Aug 2004 01:00:38 +0000 (01:00 +0000)
committerKevin Ryde <user42@zip.com.au>
Fri, 27 Aug 2004 01:00:38 +0000 (01:00 +0000)
using char class [(] etc since \( in fact makes them become special in
regexp/basic.

ice-9/regex.scm

index d49a9b5..0f5016c 100644 (file)
           string-match regexp-substitute fold-matches list-matches
           regexp-substitute/global))
 
+;; References:
+;;
+;; POSIX spec:
+;; http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html
+
 ;;; FIXME:
 ;;;   It is not clear what should happen if a `match' function
 ;;;   is passed a `match number' which is out of bounds for the
                (loop (+ 1 i)))
               (else #f)))))
 
+;; * . \ ^ $ and [ are special in both regexp/basic and regexp/extended and
+;; can be backslash escaped.
+;;
+;; ( ) + ? { } and | are special in regexp/extended so must be quoted.  But
+;; that can't be done with a backslash since in regexp/basic where they're
+;; not special, adding a backslash makes them become special.  Character
+;; class forms [(] etc are used instead.
+;;
+;; ) is not special when not preceded by a (, and * and ? are not special at
+;; the start of a string, but we quote all of these always, so the result
+;; can be concatenated or merged into some larger regexp.
+;;
+;; ] is not special outside a [ ] character class, so doesn't need to be
+;; quoted.
+;;
 (define (regexp-quote string)
   (call-with-output-string
    (lambda (p)
        (and (< i (string-length string))
            (begin
              (case (string-ref string i)
-               ((#\* #\. #\( #\) #\+ #\? #\\ #\^ #\$ #\{ #\})
-                (write-char #\\ p)))
-             (write-char (string-ref string i) p)
+               ((#\* #\. #\\ #\^ #\$ #\[)
+                (write-char #\\ p)
+                (write-char (string-ref string i) p))
+               ((#\( #\) #\+ #\? #\{ #\} #\|)
+                (write-char #\[ p)
+                (write-char (string-ref string i) p)
+                (write-char #\] p))
+               (else
+                (write-char (string-ref string i) p)))
              (loop (1+ i))))))))
 
 (define (match:start match . args)