package main
import (
"log"
)
func match(pat, s string) bool {
next := func(i, j int) bool {
return match(pat[i:], s[j:])
}
switch {
case pat == "":
return s == ""
case s == "":
return pat == ""
case pat[0] == '\\' && len(pat) > 1:
return next(2, 1)
}
switch pat[0] {
case '*':
for i := range s {
if next(1, i) {
return true
}
}
return false
case '?':
return next(1, 1)
}
return pat[0] == s[0] && next(1, 1)
}
func main() {
type t []struct {
s string
expected bool
}
groups := []struct {
pat string
tests t
}{
{"", t{
{"", true},
{"aa", false},
}},
{"aa", t{
{"aa", true},
{"", false},
}},
{`a\*a\?a`, t{
{"a*a?a", true},
{"aaa", false},
}},
{`\`, t{
{"\\", true},
{"aaa", false},
}},
{"a?*bb*cd", t{
{"aababbcd", true},
{"abcd", false},
{"aa?bxcxd", false},
}},
{"a*?b*c*d", t{
{"abcd", false},
{"aabcd", true},
{"a?bcd", true},
{"aa?bxcxd", true},
{"aa?bxcd", true},
}},
{"as*d*?qwe*qwe", t{
{"as123dssqwe12345678qwe", true},
}},
}
ok := func(got, expect bool) string {
if got == expect {
return " ok "
} else {
return "fail"
}
}
for _, group := range groups {
for _, test := range group.tests {
res := match(group.pat, test.s)
log.
Printf("[%s] %30q ~ %-20q %v", ok(res, test.expected), test.s, group.pat, res)
}
}
}
cGFja2FnZSBtYWluCgppbXBvcnQgKAoJImxvZyIKKQoKZnVuYyBtYXRjaChwYXQsIHMgc3RyaW5nKSBib29sIHsKCW5leHQgOj0gZnVuYyhpLCBqIGludCkgYm9vbCB7CgkJcmV0dXJuIG1hdGNoKHBhdFtpOl0sIHNbajpdKQoJfQoJc3dpdGNoIHsKCWNhc2UgcGF0ID09ICIiOgoJCXJldHVybiBzID09ICIiCgljYXNlIHMgPT0gIiI6CgkJcmV0dXJuIHBhdCA9PSAiIgoJY2FzZSBwYXRbMF0gPT0gJ1xcJyAmJiBsZW4ocGF0KSA+IDE6CgkJcmV0dXJuIG5leHQoMiwgMSkKCX0KCXN3aXRjaCBwYXRbMF0gewoJY2FzZSAnKic6CgkJZm9yIGkgOj0gcmFuZ2UgcyB7CgkJCWlmIG5leHQoMSwgaSkgewoJCQkJcmV0dXJuIHRydWUKCQkJfQoJCX0KCQlyZXR1cm4gZmFsc2UKCWNhc2UgJz8nOgoJCXJldHVybiBuZXh0KDEsIDEpCgl9CglyZXR1cm4gcGF0WzBdID09IHNbMF0gJiYgbmV4dCgxLCAxKQp9CgpmdW5jIG1haW4oKSB7Cgl0eXBlIHQgW11zdHJ1Y3QgewoJCXMgICAgICAgIHN0cmluZwoJCWV4cGVjdGVkIGJvb2wKCX0KCWdyb3VwcyA6PSBbXXN0cnVjdCB7CgkJcGF0ICAgc3RyaW5nCgkJdGVzdHMgdAoJfXsKCQl7IiIsIHR7CgkJCXsiIiwgdHJ1ZX0sCgkJCXsiYWEiLCBmYWxzZX0sCgkJfX0sCgkJeyJhYSIsIHR7CgkJCXsiYWEiLCB0cnVlfSwKCQkJeyIiLCBmYWxzZX0sCgkJfX0sCgkJe2BhXCphXD9hYCwgdHsKCQkJeyJhKmE/YSIsIHRydWV9LAoJCQl7ImFhYSIsIGZhbHNlfSwKCQl9fSwKCQl7YFxgLCB0ewoJCQl7IlxcIiwgdHJ1ZX0sCgkJCXsiYWFhIiwgZmFsc2V9LAoJCX19LAoJCXsiYT8qYmIqY2QiLCB0ewoJCQl7ImFhYmFiYmNkIiwgdHJ1ZX0sCgkJCXsiYWJjZCIsIGZhbHNlfSwKCQkJeyJhYT9ieGN4ZCIsIGZhbHNlfSwKCQl9fSwKCQl7ImEqP2IqYypkIiwgdHsKCQkJeyJhYmNkIiwgZmFsc2V9LAoJCQl7ImFhYmNkIiwgdHJ1ZX0sCgkJCXsiYT9iY2QiLCB0cnVlfSwKCQkJeyJhYT9ieGN4ZCIsIHRydWV9LAoJCQl7ImFhP2J4Y2QiLCB0cnVlfSwKCQl9fSwKCQl7ImFzKmQqP3F3ZSpxd2UiLCB0ewoJCQl7ImFzMTIzZHNzcXdlMTIzNDU2Nzhxd2UiLCB0cnVlfSwKCQl9fSwKCX0KCW9rIDo9IGZ1bmMoZ290LCBleHBlY3QgYm9vbCkgc3RyaW5nIHsKCQlpZiBnb3QgPT0gZXhwZWN0IHsKCQkJcmV0dXJuICIgb2sgIgoJCX0gZWxzZSB7CgkJCXJldHVybiAiZmFpbCIKCQl9Cgl9Cglmb3IgXywgZ3JvdXAgOj0gcmFuZ2UgZ3JvdXBzIHsKCQlmb3IgXywgdGVzdCA6PSByYW5nZSBncm91cC50ZXN0cyB7CgkJCXJlcyA6PSBtYXRjaChncm91cC5wYXQsIHRlc3QucykKCQkJbG9nLlByaW50ZigiWyVzXSAlMzBxIH4gJS0yMHEgJXYiLAoJCQkJb2socmVzLCB0ZXN0LmV4cGVjdGVkKSwgdGVzdC5zLCBncm91cC5wYXQsIHJlcykKCQl9Cgl9Cn0K