Translate a shell-style pattern to a regular expression. The pattern may include ``** `` ( stands for the platform-specific path separator; "/" on POSIX systems) for matching zero or more directory levels and "*" for matching zero or more arbitrary characters except any path se
(pat, match_end=r"\Z")
| 4 | |
| 5 | |
| 6 | def translate(pat, match_end=r"\Z"): |
| 7 | """Translate a shell-style pattern to a regular expression. |
| 8 | |
| 9 | The pattern may include ``**<sep>`` (<sep> stands for the platform-specific path separator; "/" on POSIX systems) |
| 10 | for matching zero or more directory levels and "*" for matching zero or more arbitrary characters except any path |
| 11 | separator. Wrap meta-characters in brackets for a literal match (i.e., "[?]" to match the literal character "?"). |
| 12 | |
| 13 | Using ``match_end=REGEX`` you can provide a regular expression that is appended after the pattern-derived |
| 14 | expression. The default is to match the end of the string. |
| 15 | |
| 16 | This function is derived from the "fnmatch" module distributed with the Python standard library. |
| 17 | |
| 18 | :copyright: 2001-2016 Python Software Foundation. All rights reserved. |
| 19 | :license: PSFLv2 |
| 20 | """ |
| 21 | pat = _translate_alternatives(pat) |
| 22 | |
| 23 | sep = os.path.sep |
| 24 | n = len(pat) |
| 25 | i = 0 |
| 26 | res = "" |
| 27 | |
| 28 | while i < n: |
| 29 | c = pat[i] |
| 30 | i += 1 |
| 31 | |
| 32 | if c == "*": |
| 33 | if i + 1 < n and pat[i] == "*" and pat[i + 1] == sep: |
| 34 | # **/ == wildcard for 0+ full (relative) directory names with trailing slashes; the forward slash stands |
| 35 | # for the platform-specific path separator |
| 36 | res += rf"(?:[^\{sep}]*\{sep})*" |
| 37 | i += 2 |
| 38 | else: |
| 39 | # * == wildcard for name parts (does not cross path separator) |
| 40 | res += r"[^\%s]*" % sep |
| 41 | elif c == "?": |
| 42 | # ? == any single character excluding path separator |
| 43 | res += r"[^\%s]" % sep |
| 44 | elif c == "[": |
| 45 | j = i |
| 46 | if j < n and pat[j] == "!": |
| 47 | j += 1 |
| 48 | if j < n and pat[j] == "]": |
| 49 | j += 1 |
| 50 | while j < n and pat[j] != "]": |
| 51 | j += 1 |
| 52 | if j >= n: |
| 53 | res += "\\[" |
| 54 | else: |
| 55 | stuff = pat[i:j].replace("\\", "\\\\") |
| 56 | i = j + 1 |
| 57 | if stuff[0] == "!": |
| 58 | stuff = "^" + stuff[1:] |
| 59 | elif stuff[0] == "^": |
| 60 | stuff = "\\" + stuff |
| 61 | res += "[%s]" % stuff |
| 62 | elif c in "(|)": |
| 63 | if i > 0 and pat[i - 1] != "\\": |
nothing calls this directly
no test coverage detected