fnmatch.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file).
  2. // All rights reserved. Use of this source code is governed by an MIT-style
  3. // license that can be found in the LICENSE file.
  4. package fnmatch
  5. import (
  6. "path/filepath"
  7. "regexp"
  8. "runtime"
  9. "strings"
  10. )
  11. const (
  12. FNM_NOESCAPE = (1 << iota)
  13. FNM_PATHNAME
  14. FNM_CASEFOLD
  15. )
  16. func Convert(pattern string, flags int) (*regexp.Regexp, error) {
  17. any := "."
  18. switch runtime.GOOS {
  19. case "windows":
  20. flags |= FNM_NOESCAPE | FNM_CASEFOLD
  21. pattern = filepath.FromSlash(pattern)
  22. if flags&FNM_PATHNAME != 0 {
  23. any = "[^\\\\]"
  24. }
  25. case "darwin":
  26. flags |= FNM_CASEFOLD
  27. fallthrough
  28. default:
  29. if flags&FNM_PATHNAME != 0 {
  30. any = "[^/]"
  31. }
  32. }
  33. if flags&FNM_NOESCAPE != 0 {
  34. pattern = strings.Replace(pattern, "\\", "\\\\", -1)
  35. } else {
  36. pattern = strings.Replace(pattern, "\\*", "[:escapedstar:]", -1)
  37. pattern = strings.Replace(pattern, "\\?", "[:escapedques:]", -1)
  38. pattern = strings.Replace(pattern, "\\.", "[:escapeddot:]", -1)
  39. }
  40. pattern = strings.Replace(pattern, ".", "\\.", -1)
  41. pattern = strings.Replace(pattern, "**", "[:doublestar:]", -1)
  42. pattern = strings.Replace(pattern, "*", any+"*", -1)
  43. pattern = strings.Replace(pattern, "[:doublestar:]", ".*", -1)
  44. pattern = strings.Replace(pattern, "?", any, -1)
  45. pattern = strings.Replace(pattern, "[:escapedstar:]", "\\*", -1)
  46. pattern = strings.Replace(pattern, "[:escapedques:]", "\\?", -1)
  47. pattern = strings.Replace(pattern, "[:escapeddot:]", "\\.", -1)
  48. pattern = "^" + pattern + "$"
  49. if flags&FNM_CASEFOLD != 0 {
  50. pattern = "(?i)" + pattern
  51. }
  52. return regexp.Compile(pattern)
  53. }
  54. // Matches the pattern against the string, with the given flags,
  55. // and returns true if the match is successful.
  56. func Match(pattern, s string, flags int) (bool, error) {
  57. exp, err := Convert(pattern, flags)
  58. if err != nil {
  59. return false, err
  60. }
  61. return exp.MatchString(s), nil
  62. }