@@ -87,7 +87,9 @@ def _translate(pat, star, question_mark):
8787 res = []
8888 add = res .append
8989 star_indices = []
90- inside_range = False
90+ inside_range = False
91+ add_negative_lookahead = False
92+ question_mark_char = re .sub (r'\[|\]|\^' , '' , question_mark )
9193
9294 i , n = 0 , len (pat )
9395 while i < n :
@@ -136,21 +138,13 @@ def _translate(pat, star, question_mark):
136138 if chunks [k - 1 ][- 1 ] > chunks [k ][0 ]:
137139 chunks [k - 1 ] = chunks [k - 1 ][:- 1 ] + chunks [k ][1 :]
138140 del chunks [k ]
139-
140141 if len (chunks )> 1 :
141- char_range = set (range (ord (chunks [0 ][- 1 ]), ord (chunks [- 1 ][0 ])))
142-
143- question_mark_char = question_mark .replace ('\\ ' , '' ).replace ('[' , '' ).replace (']' , '' ).replace ('^' , '' )
144- question_mark_char = set (map (ord , question_mark_char ))
145-
146- if question_mark_char .intersection (char_range ):
147- inside_range = True
148-
142+ if question_mark_char :
143+ inside_range = chunks [0 ][- 1 ] <= question_mark_char <= chunks [- 1 ][0 ]
149144 # Escape backslashes and hyphens for set difference (--).
150145 # Hyphens that create ranges shouldn't be escaped.
151146 stuff = '-' .join (s .replace ('\\ ' , r'\\' ).replace ('-' , r'\-' )
152147 for s in chunks )
153-
154148 i = j + 1
155149 if not stuff :
156150 # Empty range: never match.
@@ -159,14 +153,22 @@ def _translate(pat, star, question_mark):
159153 # Negated empty range: match any character.
160154 add (question_mark )
161155 else :
156+ negative_lookahead = ''
162157 if question_mark != '.' and inside_range :
163- add (f'(?={ question_mark } )' )
158+ add_negative_lookahead = True
159+ negative_lookahead = negative_lookahead + question_mark_char
164160 # Escape set operations (&&, ~~ and ||).
165161 stuff = _re_setops_sub (r'\\\1' , stuff )
166162 if stuff [0 ] == '!' :
163+ if question_mark_char not in stuff and question_mark != '.' :
164+ add_negative_lookahead = True
165+ negative_lookahead = negative_lookahead + question_mark_char
167166 stuff = '^' + stuff [1 :]
168- elif stuff [0 ] in ('^' , '[' ):
167+ elif stuff [0 ] in ('^' , '[' , question_mark_char ):
169168 stuff = '\\ ' + stuff
169+ if add_negative_lookahead :
170+ add (f'(?![{ negative_lookahead } ])' )
171+ add_negative_lookahead = False
170172 add (f'[{ stuff } ]' )
171173 else :
172174 add (_re_escape (c ))
0 commit comments