|
按规则解析并替换字符串中的变量及函数
需求
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}
复制代码 来源:https://www.cnblogs.com/shouke/p/17843050.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
|