Translates the shell-style alternative portions of the pattern to regular expression groups. For example: {alt1,alt2} -> (alt1|alt2)
(pat)
| 106 | |
| 107 | |
| 108 | def _translate_alternatives(pat): |
| 109 | """Translates the shell-style alternative portions of the pattern to regular expression groups. |
| 110 | |
| 111 | For example: {alt1,alt2} -> (alt1|alt2) |
| 112 | """ |
| 113 | # Parse pattern for paired braces. |
| 114 | brace_pairs = _parse_braces(pat) |
| 115 | |
| 116 | pat_list = list(pat) # Convert to list in order to subscript characters. |
| 117 | |
| 118 | # Convert non-escaped commas within groups to pipes. |
| 119 | # Passing, e.g. "{a\,b}.txt" to the shell expands to "{a,b}.txt", whereas |
| 120 | # "{a\,,b}.txt" expands to "a,.txt" and "b.txt" |
| 121 | for opening, closing in brace_pairs: |
| 122 | commas = 0 |
| 123 | |
| 124 | for i in range(opening + 1, closing): # Convert non-escaped commas to pipes. |
| 125 | if pat_list[i] == ",": |
| 126 | if i == opening or pat_list[i - 1] != "\\": |
| 127 | pat_list[i] = "|" |
| 128 | commas += 1 |
| 129 | elif pat_list[i] == "|" and (i == opening or pat_list[i - 1] != "\\"): |
| 130 | # Nested groups have their commas converted to pipes when traversing the parent group. |
| 131 | # So in order to confirm the presence of a comma in the original, shell-style pattern, |
| 132 | # we must also check for a pipe. |
| 133 | commas += 1 |
| 134 | |
| 135 | # Convert paired braces into parentheses, but only if at least one comma is present. |
| 136 | if commas > 0: |
| 137 | pat_list[opening] = "(" |
| 138 | pat_list[closing] = ")" |
| 139 | |
| 140 | return "".join(pat_list) |
no test coverage detected