fix: match duplicate variable/function in raw string

e.g.

"ABC${func1($var_1, $var_3)}$var_1--${func1($var_1, $var_3)}$var_1"
This commit is contained in:
debugtalk
2019-04-17 15:17:36 +08:00
parent 04248ee7e1
commit 920df9985c
2 changed files with 54 additions and 46 deletions

View File

@@ -436,48 +436,57 @@ class LazyString(object):
args: ["${func2($a, $b)}", "$c"] args: ["${func2($a, $b)}", "$c"]
""" """
self._string = raw_string self._args = []
args_mapping = {}
# Notice: functions must be handled before variables try:
# search function like ${func($a, $b)} match_start_position = raw_string.index("$", 0)
func_match_list = regex_findall_functions(self._string) self._string = raw_string[0:match_start_position]
match_start_position = 0 except ValueError:
for func_match in func_match_list: self._string = raw_string
func_str = "${%s(%s)}" % (func_match[0], func_match[1]) return
match_start_position = raw_string.index(func_str, match_start_position)
self._string = self._string.replace(func_str, "{}", 1)
function_meta = parse_function_params(func_match[1])
function_meta = {
"func_name": func_match[0]
}
function_meta.update(parse_function_params(func_match[1]))
lazy_func = LazyFunction(
function_meta,
self.functions_mapping,
self.check_variables_set
)
args_mapping[match_start_position] = lazy_func
match_start_position += len(func_str)
# search variable like $var while match_start_position < len(raw_string):
var_match_list = regex_findall_variables(self._string)
match_start_position = 0
for var_name in var_match_list:
# check if any variable undefined in check_variables_set
if var_name not in self.check_variables_set:
raise exceptions.VariableNotFound(var_name)
var = "${}".format(var_name) # Notice: functions must be handled before variables
match_start_position = raw_string.index(var, match_start_position) # search function like ${func($a, $b)}
# TODO: escape '{' and '}' func_match = function_regex_compile.match(raw_string, match_start_position)
# self._string = self._string.replace("{", "{{") if func_match:
# self._string = self._string.replace("}", "}}") function_meta = parse_function_params(func_match[1])
self._string = self._string.replace(var, "{}", 1) function_meta = {
args_mapping[match_start_position] = var_name "func_name": func_match[1]
match_start_position += len(var) }
function_meta.update(parse_function_params(func_match[2]))
lazy_func = LazyFunction(
function_meta,
self.functions_mapping,
self.check_variables_set
)
self._args.append(lazy_func)
match_start_position = func_match.end()
self._string += "{}"
continue
self._args = [args_mapping[key] for key in sorted(args_mapping.keys())] # search variable like $var
var_match = variable_regex_compile.match(raw_string, match_start_position)
if var_match:
var_name = var_match.group(1)
# check if any variable undefined in check_variables_set
if var_name not in self.check_variables_set:
raise exceptions.VariableNotFound(var_name)
self._args.append(var_name)
match_start_position = var_match.end()
self._string += "{}"
continue
curr_position = match_start_position
try:
# find next $ location
match_start_position = raw_string.index("$", curr_position+1)
self._string += raw_string[curr_position:match_start_position]
except ValueError:
self._string += raw_string[curr_position:]
break
def __repr__(self): def __repr__(self):
return "LazyString({})".format(self.raw_string) return "LazyString({})".format(self.raw_string)

View File

@@ -378,14 +378,13 @@ class TestParserBasic(unittest.TestCase):
self.assertEqual(var._string, "ABC{}{}") self.assertEqual(var._string, "ABC{}{}")
self.assertEqual(var.to_value(variables_mapping), "ABCabc123abc") self.assertEqual(var.to_value(variables_mapping), "ABCabc123abc")
# TODO: fix var = parser.LazyString(
# var = parser.LazyString( "ABC${func1($var_1, $var_3)}$var_1--${func1($var_1, $var_3)}$var_1",
# "ABC${func1($var_1, $var_3)}$var_1--${func1($var_1, $var_3)}$var_1", functions_mapping,
# functions_mapping, check_variables_set
# check_variables_set )
# ) self.assertEqual(var._string, "ABC{}{}--{}{}")
# self.assertEqual(var._string, "ABC{}{}--{}{}") self.assertEqual(var.to_value(variables_mapping), "ABCabc123abc--abc123abc")
# self.assertEqual(var.to_value(variables_mapping), "ABCabc123abc--abc123abc")
var = parser.LazyString("ABC${func1($var_1, $var_3)}DE$var_4", functions_mapping, check_variables_set) var = parser.LazyString("ABC${func1($var_1, $var_3)}DE$var_4", functions_mapping, check_variables_set)
self.assertEqual(var._string, "ABC{}DE{}") self.assertEqual(var._string, "ABC{}DE{}")