fork(2) download
  1. (defmacro case-it (keyform &body cases)
  2. `(let ((it ,keyform))
  3. (case it ,@cases)))
  4.  
  5. (defun match% (pattern string start end)
  6. (macrolet ((match%% (i)
  7. `(match% pattern string ,i end))
  8. (next-pattern ()
  9. `(or (pop pattern) (error "Pattern is incorrect"))))
  10. (cond ((null pattern) (= start end))
  11. ((= start end) nil)
  12. (t
  13. (case-it (next-pattern)
  14. (#\? (match%% (1+ start)))
  15. (#\\ (and (eql (aref string start)
  16. (next-pattern))
  17. (match%% (1+ start))))
  18. (#\* (loop :for i :from start :to end
  19. :for match-p := (match%% i) :until match-p
  20. :finally (return match-p)))
  21. (t (and (eql it (aref string start))
  22. (match%% (1+ start)))))))))
  23.  
  24. (defun match (pattern string &key (start 0) (end (length string)))
  25. (match% (coerce pattern 'list) string start end))
  26.  
  27. (loop :for (s r) :on '("abcd" nil
  28. "aabcd" t
  29. "a?bcd" t
  30. "aa?bxcxd" t
  31. "aa?bxcd" t) :by #'cddr
  32. :for x := (match "a*?b*c*d" s) :do
  33. (format t "~:[FAIL~;OK~] ~:S: expected ~:[false~;true~]~%" (eq r x) s r))
Success #stdin #stdout 0.01s 10544KB
stdin
Standard input is empty
stdout
OK "abcd": expected false
OK "aabcd": expected true
OK "a?bcd": expected true
OK "aa?bxcxd": expected true
OK "aa?bxcd": expected true