PageRenderTime 34ms CodeModel.GetById 8ms RepoModel.GetById 1ms app.codeStats 0ms

/sphinx/util/matching.py

https://bitbucket.org/birkenfeld/sphinx/
Python | 80 lines | 59 code | 3 blank | 18 comment | 18 complexity | 0091ef15b8fa1be78b9cb142f87c4a1f MD5 | raw file
Possible License(s): BSD-2-Clause
  1. # -*- coding: utf-8 -*-
  2. """
  3. sphinx.util.matching
  4. ~~~~~~~~~~~~~~~~~~~~
  5. Pattern-matching utility functions for Sphinx.
  6. :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
  7. :license: BSD, see LICENSE for details.
  8. """
  9. import re
  10. def _translate_pattern(pat):
  11. """Translate a shell-style glob pattern to a regular expression.
  12. Adapted from the fnmatch module, but enhanced so that single stars don't
  13. match slashes.
  14. """
  15. i, n = 0, len(pat)
  16. res = ''
  17. while i < n:
  18. c = pat[i]
  19. i += 1
  20. if c == '*':
  21. if i < n and pat[i] == '*':
  22. # double star matches slashes too
  23. i += 1
  24. res = res + '.*'
  25. else:
  26. # single star doesn't match slashes
  27. res = res + '[^/]*'
  28. elif c == '?':
  29. # question mark doesn't match slashes too
  30. res = res + '[^/]'
  31. elif c == '[':
  32. j = i
  33. if j < n and pat[j] == '!':
  34. j += 1
  35. if j < n and pat[j] == ']':
  36. j += 1
  37. while j < n and pat[j] != ']':
  38. j += 1
  39. if j >= n:
  40. res = res + '\\['
  41. else:
  42. stuff = pat[i:j].replace('\\', '\\\\')
  43. i = j + 1
  44. if stuff[0] == '!':
  45. # negative pattern mustn't match slashes too
  46. stuff = '^/' + stuff[1:]
  47. elif stuff[0] == '^':
  48. stuff = '\\' + stuff
  49. res = '%s[%s]' % (res, stuff)
  50. else:
  51. res += re.escape(c)
  52. return res + '$'
  53. def compile_matchers(patterns):
  54. return [re.compile(_translate_pattern(pat)).match for pat in patterns]
  55. _pat_cache = {}
  56. def patmatch(name, pat):
  57. """Return if name matches pat. Adapted from fnmatch module."""
  58. if pat not in _pat_cache:
  59. _pat_cache[pat] = re.compile(_translate_pattern(pat))
  60. return _pat_cache[pat].match(name)
  61. def patfilter(names, pat):
  62. """Return the subset of the list NAMES that match PAT.
  63. Adapted from fnmatch module.
  64. """
  65. if pat not in _pat_cache:
  66. _pat_cache[pat] = re.compile(_translate_pattern(pat))
  67. match = _pat_cache[pat].match
  68. return list(filter(match, names))