match.go 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. package pattern
  2. import (
  3. "fmt"
  4. "regexp"
  5. )
  6. // Match is a wrapper of *regexp.Regexp.
  7. // It contains the match pattern compiled into a regular expression.
  8. type Match struct {
  9. *regexp.Regexp
  10. }
  11. // Compile takes our match expression as a string, and compiles it into a *Match object.
  12. // Will return an error on an invalid pattern.
  13. func MatchCompile(pattern string) (match *Match, err error) {
  14. regex := ""
  15. escaped := false
  16. arr := []byte(pattern)
  17. for i := 0; i < len(arr); i++ {
  18. if escaped {
  19. escaped = false
  20. switch arr[i] {
  21. case '*', '?', '\\':
  22. regex += "\\" + string(arr[i])
  23. default:
  24. return nil, fmt.Errorf("Invalid escaped character '%c'", arr[i])
  25. }
  26. } else {
  27. switch arr[i] {
  28. case '\\':
  29. escaped = true
  30. case '*':
  31. regex += ".*"
  32. case '?':
  33. regex += "."
  34. case '.', '(', ')', '+', '|', '^', '$', '[', ']', '{', '}':
  35. regex += "\\" + string(arr[i])
  36. default:
  37. regex += string(arr[i])
  38. }
  39. }
  40. }
  41. if escaped {
  42. return nil, fmt.Errorf("Unterminated escape at end of pattern")
  43. }
  44. var r *regexp.Regexp
  45. if r, err = regexp.Compile("^" + regex + "$"); err != nil {
  46. return nil, err
  47. }
  48. return &Match{r}, nil
  49. }