13
13
"""Compared with the standard library, syntax '{seq1,seq2}' is supported"""
14
14
15
15
import functools
16
+ import io
16
17
import os
17
18
import re
18
19
from typing import Callable , List , Match , Optional
@@ -71,14 +72,9 @@ def _compat(res: str) -> str:
71
72
return r"(?s:%s)\Z" % res
72
73
73
74
74
- def translate (pat : str ) -> str :
75
- """Translate a shell PATTERN to a regular expression.
76
-
77
- There is no way to quote meta-characters.
78
- """
79
-
75
+ def _translate (pat : str , match_curly : bool ) -> str :
80
76
i , n = 0 , len (pat )
81
- res = ""
77
+ buf = io . StringIO ()
82
78
while i < n :
83
79
c = pat [i ]
84
80
i = i + 1
@@ -90,14 +86,14 @@ def translate(pat: str) -> str:
90
86
if (j < n and pat [j ] == "/" ) and (i <= 1 or pat [i - 2 ] == "/" ):
91
87
# hit /**/ instead of /seq**/
92
88
j = j + 1
93
- res = res + r"(.*/)?"
89
+ buf . write ( r"(.*/)?" )
94
90
else :
95
- res = res + r".*"
91
+ buf . write ( r".*" )
96
92
else :
97
- res = res + r"[^/]*"
93
+ buf . write ( r"[^/]*" )
98
94
i = j
99
95
elif c == "?" :
100
- res = res + r"."
96
+ buf . write ( r"." )
101
97
elif c == "[" :
102
98
j = i
103
99
if j < n and pat [j ] == "!" :
@@ -107,28 +103,37 @@ def translate(pat: str) -> str:
107
103
while j < n and pat [j ] != "]" :
108
104
j = j + 1
109
105
if j >= n :
110
- res = res + r"\["
106
+ buf . write ( r"\[" )
111
107
else :
112
108
stuff = pat [i :j ].replace ("\\ " , r"\\" )
113
109
i = j + 1
114
110
if stuff [0 ] == "!" :
115
111
stuff = r"^" + stuff [1 :]
116
112
elif stuff [0 ] == "^" :
117
113
stuff = "\\ " + stuff
118
- res = r"%s [%s]" % ( res , stuff )
119
- elif c == "{" :
114
+ buf . write ( r" [%s]" % stuff )
115
+ elif match_curly and c == "{" :
120
116
j = i
121
117
if j < n and pat [j ] == "}" :
122
118
j = j + 1
123
119
while j < n and pat [j ] != "}" :
124
120
j = j + 1
125
121
if j >= n :
126
- res = res + r"\{"
122
+ buf . write ( r"\{" )
127
123
else :
128
124
stuff = pat [i :j ].replace ("\\ " , r"\\" )
129
- stuff = r"|" .join (map ( re . escape , stuff .split ("," ))) # pyre-ignore[6]
130
- res = r"%s (%s)" % ( res , stuff )
125
+ stuff = r"|" .join (_translate ( part , False ) for part in stuff .split ("," ))
126
+ buf . write ( r" (%s)" % stuff )
131
127
i = j + 1
132
128
else :
133
- res = res + re .escape (c )
134
- return _compat (res )
129
+ buf .write (re .escape (c ))
130
+ return buf .getvalue ()
131
+
132
+
133
+ def translate (pat : str ) -> str :
134
+ """Translate a shell PATTERN to a regular expression.
135
+
136
+ There is no way to quote meta-characters.
137
+ """
138
+
139
+ return _compat (_translate (pat , True ))
0 commit comments