glob.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package glob
  2. import "strings"
  3. const GLOB = "*"
  4. const maxGlobParts = 5
  5. // Glob will test a string pattern, potentially containing globs, against a
  6. // subject string. The result is a simple true/false, determining whether or
  7. // not the glob pattern matched the subject text.
  8. func Glob(pattern, subj string) bool {
  9. // Empty pattern can only match empty subject
  10. if pattern == "" {
  11. return subj == pattern
  12. }
  13. // If the pattern _is_ a glob, it matches everything
  14. if pattern == GLOB {
  15. return true
  16. }
  17. parts := strings.Split(pattern, GLOB)
  18. if len(parts) > maxGlobParts {
  19. return false // Pattern is too complex, reject it.
  20. }
  21. if len(parts) == 1 {
  22. // No globs in pattern, so test for equality
  23. return subj == pattern
  24. }
  25. leadingGlob := strings.HasPrefix(pattern, GLOB)
  26. trailingGlob := strings.HasSuffix(pattern, GLOB)
  27. end := len(parts) - 1
  28. // Go over the leading parts and ensure they match.
  29. for i := 0; i < end; i++ {
  30. idx := strings.Index(subj, parts[i])
  31. switch i {
  32. case 0:
  33. // Check the first section. Requires special handling.
  34. if !leadingGlob && idx != 0 {
  35. return false
  36. }
  37. default:
  38. // Check that the middle parts match.
  39. if idx < 0 {
  40. return false
  41. }
  42. }
  43. // Trim evaluated text from subj as we loop over the pattern.
  44. subj = subj[idx+len(parts[i]):]
  45. }
  46. // Reached the last section. Requires special handling.
  47. return trailingGlob || strings.HasSuffix(subj, parts[end])
  48. }