Python 按规则解析并替换字符串中的变量及函数(示例代码)
作者:授客
这篇文章主要介绍了Python 按规则解析并替换字符串中的变量及函数,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
按规则解析并替换字符串中的变量及函数
需求
1、按照一定规则解析字符串中的函数、变量表达式,并替换这些表达式。这些函数表达式可能包含其它函数表达式,即支持函数嵌套
2、函数表达式格式:${ __函数名称() }、${__函数名称( 函数参数 )}
3、变量表达式格式:${ varName }
注意:
- 函数名称以
__
打头 ${
之间不能有空格- 函数名称和函数的左括号
(
之间不能有空隔 - 函数支持嵌套,形如:
${ __function1( ${__function2()} )}
- 函数参数如果是字符串(包括由嵌套函数返回值),需要使用单引号、双引号引用 形如
${ __function1( "str_value", 123)}
,${ __function1(key="arg_value")}
,${ __function1(key=\'arg_value\')}
, - 函数参数支持python原生函数 形如
${ __function1( set([1,2,3]) )}
实现代码
#!/usr/bin/env python # -*- coding:utf-8 -*- import re REGEX_PATTERN_FOR_DYNAMIC = re.compile('(\${\s*.+\s*})', re.DOTALL) # 用于获取动态值中的表达式 REGEX_PATTERN_FOR_VAR = re.compile('(\${\s*[^{}]+s*})', re.DOTALL) # 用于获取动态值中的变量表达式 REGEX_PATTERN_FOR_FUNC_DEFINITION = re.compile('\${\s*__.+?\(.*?\)\s*}', re.DOTALL) # 用于获取函数表达式中的函数名称及其参数 REGEX_PATTERN_FOR_FUNC_NAME_WITH_ARGS = re.compile('\${\s*(__.+?)\((.*?)\)\s*}', re.DOTALL) # 用于获取函数表达式中的函数名称及其参数 def test_func1(): print('-----func1 called-----') def test_func2(arg1, arg2): print('-----func2 called-----') print('arg1:', arg1, 'arg2:', arg2) print() return "func2" def test_func3(arg1, arg2): print('-----func3 called-----') print('arg1:', arg1, 'arg2:', arg2) print() return 999 def test_func4(arg1, arg2): print('-----func4 called-----') print('arg1:', arg1, 'arg2:', arg2) print() return 9.99 def test_func5(arg1, arg2): print('-----func5 called-----') print('arg1:', arg1, 'arg2:', arg2) print() return ['e1', 'e2'] def test_func6(arg1, arg2): print('-----func6 called-----') print('arg1:', arg1, 'arg2:', arg2) print() return False def test_func7(*args, **kwargs): print('-----func7 called-----') for i, arg in enumerate(args): print('arg%s = %s' % (i, arg)) for i, kwargs in enumerate(kwargs): print('kwarg%s = ' % i, kwargs) user_name = 'shouke' addr = 'unknown' int_var = 3 def evaluate_dynamic_value(dynamic_value): '''解析动态值 @params: dynamic_value 动态值,如果是字符串类型,带双引号、单引号 ''' if REGEX_PATTERN_FOR_VAR.search(dynamic_value): pattern = REGEX_PATTERN_FOR_VAR elif REGEX_PATTERN_FOR_FUNC_DEFINITION.search(dynamic_value): pattern = REGEX_PATTERN_FOR_FUNC_DEFINITION else: return dynamic_value var_express_value = None match_res = pattern.findall(dynamic_value) for var_express in match_res: var_name = var_express[2:-1].strip() if var_name.startswith('__'): # 函数 function_mateched = REGEX_PATTERN_FOR_FUNC_DEFINITION.findall(var_express) for function in function_mateched: func_info_matched = REGEX_PATTERN_FOR_FUNC_NAME_WITH_ARGS.findall(var_express) for func_info in func_info_matched: func_name, func_args = func_info # print('---',func_name, func_args) if REGEX_PATTERN_FOR_DYNAMIC.search(func_args): func_args = evaluate_dynamic_value(func_args) func_value = eval('{func_name}({func_args})'.format(func_name=func_name.lstrip('_'), func_args=func_args)) if func_value is None: func_value = '' var_express_value = var_express.replace(function, str(func_value)) else: # 变量,不支持嵌套,直接取值 var_express_value = globals().get(var_name, '') if var_express_value is not None: dynamic_value = dynamic_value.replace(var_express, str(var_express_value)) if REGEX_PATTERN_FOR_DYNAMIC.search(dynamic_value): # 替换后的动态值,还是可能存在动态值 dynamic_value = evaluate_dynamic_value(dynamic_value) return dynamic_value # 测试验证 print(evaluate_dynamic_value('${ user_name }')) # 输出:shouke print(evaluate_dynamic_value('${ addr }')) # 输出:unknown print(evaluate_dynamic_value('username:${ user_name } addr:${ addr }')) # 输出:username:shouke addr:unknown print(evaluate_dynamic_value('${ __test_func1() }')) #调用输出: #-----func1 called----- print(evaluate_dynamic_value('${ __test_func2("user", "shouke") }')) # 输出:func2 #调用输出: #-----func2 called----- # arg1: user arg2: shouke # print(evaluate_dynamic_value('test_func1 return: ${ __test_func1() }, test_func2 return: ${ __test_func2("user", "shouke") }')) # 输出:test_func1 return: , test_func2 return: func2 # 调用输出: #-----func1 called----- #-----func2 called----- #arg1: user arg2: shouke # print(evaluate_dynamic_value('${ __test_func7("addr", "sz") }')) #-----func7 called----- #调用输出: #arg0 = addr #arg1 = sz print(evaluate_dynamic_value('${ __test_func7(110,' ' 11.56, ' '"test", ' '[1, 3, 5], ' '["2", "4", "6"], ' '1 == 1, ' 'True, ' '{"username": "shouke", "age": "unknown"},' 'position="sz",' 'hobby="pingpong",' 'books=["unkonwn"]) }')) #调用输出: # -----func7 called----- # arg0 = 110 # arg1 = 11.56 # arg2 = test # arg3 = [1, 3, 5] # arg4 = ['2', '4', '6'] # arg5 = True # arg6 = True # arg7 = {'username': 'shouke', 'age': 'unknown'} # kwarg0 = position # kwarg1 = hobby # kwarg2 = books print(evaluate_dynamic_value('${ __test_func7("${user_name}", ${int_var})}')) #调用输出: #-----func7 called----- #arg0 = shouke #arg1 = 3 print(evaluate_dynamic_value('var: ${addr} function: ${ __test_func7( ${__test_func6("${user_name}", ${int_var})}, ${__test_func5( ${__test_func4("${int_var}", "func4")}, ${__test_func3(\'${__test_func2("func2", True)}\', \'func3\')} )})}')) # 返回 var: unknown function: #调用输出: #-----func6 called----- #arg1: shouke arg2: 3 # #-----func4 called----- #arg1: 3 arg2: func4 # #-----func2 called----- #arg1: func2 arg2: True # #-----func3 called----- #arg1: func2 arg2: func3 # #-----func5 called----- #arg1: 9.99 arg2: 999 # #-----func7 called----- #arg0 = False #arg1 = ['e1', 'e2'] #-----func2 called----- #arg1: func2 arg2: True # #-----func4 called----- #arg1: 3 arg2: func4 # #-----func2 called----- #arg1: func2 arg2: True # #-----func2 called----- #arg1: func2 arg2: True # #-----func2 called----- #arg1: func2 arg2: True # #-----func2 called----- #arg1: func2 arg2: True # print(evaluate_dynamic_value('${ __test_func7(set([1, 2, 3]))}')) #调用输出: # -----func7 called----- # arg0 = {1, 2, 3}
到此这篇关于Python 按规则解析并替换字符串中的变量及函数的文章就介绍到这了,更多相关Python 替换字符串变量及函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!