pcond

PCOND is a conditional macro that does pattern matching, hence the "P" in the name. It was created and is maintained by Eric Normand. It depends on cl-ppcre and cl-unification.

It binds variables to the values it matches to. Those bindings are available in the body of the conditional.

It currently has three pattern types it matches:

Another great feature is that you can "nest" the conditionals.
Examples

* (pcond:pcond 
    ((and (:pat (?x . ?xs) '(a b))
          (:re "xyz" "xyz"))
       'match))
MATCH
* (pcond:pcond
     ((and (:re "ab(\\d*)" "ab12" ((#'parse-integer num)))
           (some #'(lambda (x)
                     (and (:pat (?x ?y . ?rest) x)
	 		 (= ?y num)))
                 '((a 1) (b 2 h) (c 12 j) (f 12))))
        ?x))
C

Examples:

(defun my-map (fn ls)
  (pcond:pcond
    ((null ls)
      nil)
    ((:pat (?x . ?xs) ls)
      (cons (funcall fn ?x) (my-map fn ?xs)))))

(defun path-parser (path)
  (pcond:pcond
    ((or (null path) (:pat "" path))
      nil)
    ((:re "^(/)(.*)" path (slash rst))
      (cons "/" (path-parser rst)))
    ((:re "^([^/]*)/(.*)" path (1st rst))
      (cons 1st (path-parser rst)))
    (t (list path))))
Output:
* (path-parser "")
nil
* (path-parser "/")
("/")
* (path-parser "/a/b/c")
("/" "a" "b" "c")

In addition, the conditional is extensible. You can add your own pattern types to match to.

Download ASDF package from http://www.lispcast.com/files/packages/pcond_current.tar.gz

CLiki pages can be edited by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively