I have always missed the ease provided by Perl in throwing a string at a list of regular expressions. I have thought it would be nice if the (ice-9 regex) module would provide something comparable . So I started work on a macro “regex-case”. Code attached. Comments on syntax appreciated. — Matt
=== test ================
(define str "foo")
(regex-case str
(("^([a-z]+)\\(([0-9]+)\\)$" v i)
(list v i))
(("^([a-z]+)$" v)
(list v "1”)))
=>
(“foo” “1”)
=== syntax ==============
(regex-case <string>
((<pattern> <var> <var> …) <body>)
((<pattern> <var> <var> …) <body>)
(else <body>)
Where <pattern> is a string form of a regular expression, <var> … are variables
that are bound to the matched subexpressions, and <body> is a list of
expressions. The return is the last expression of the matched case.
=== expansion ===========
The example shown above expands to:
(let ((t-292 (make-regexp "^([a-z]+)\\(([0-9]+)\\)$"))
(t-293 (make-regexp "^([a-z]+)$")))
(cond ((regexp-exec t-292 str)
=>
(lambda (m)
(let ((v (match:substring m 1))
(i (match:substring m 2)))
(list v i))))
((regexp-exec t-293 str)
=>
(lambda (m)
(let ((v (match:substring m 1))) (list v "1"))))))
I was thinking the above expansion has some chance (if it lives in the regex
module?) to memoize the make-regexp part during optimization.
If not a macro could be written to generate a match function which can memoize
the make-regexp part.
(define regex-matcher foo ((<pattern> …)
=>
(define (let ((t-123 (make-regex <pattern>)) …) (lambda (str) (cond
((regexp-exec t-123 str) ...
regex-case.scm
Description: Binary data
