翼度科技»论坛 编程开发 python 查看内容

Python 按规则解析并替换字符串中的变量及函数

10

主题

10

帖子

30

积分

新手上路

Rank: 1

积分
30
按规则解析并替换字符串中的变量及函数

需求

1、按照一定规则解析字符串中的函数、变量表达式,并替换这些表达式。这些函数表达式可能包含其它函数表达式,即支持函数嵌套
2、函数表达式格式:${  __函数名称()  }、${__函数名称( 函数参数 )}
3、变量表达式格式:${ varName }
注意:

  • 函数名称以__打头
  • ${  之间不能有空格
  • 函数名称和函数的左括号 ( 之间不能有空隔
  • 函数支持嵌套,形如:${ __function1( ${__function2()} )}
  • 函数参数如果是字符串(包括由嵌套函数返回值),需要使用单引号、双引号引用 形如 ${ __function1( "str_value",  123)} ,${ __function1(key="arg_value")},${ __function1(key=\'arg_value\')},
  • 函数参数支持python原生函数 形如  ${ __function1( set([1,2,3]) )}
实现代码
  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. import re
  4. REGEX_PATTERN_FOR_DYNAMIC =  re.compile('(\${\s*.+\s*})', re.DOTALL) # 用于获取动态值中的表达式
  5. REGEX_PATTERN_FOR_VAR = re.compile('(\${\s*[^{}]+s*})', re.DOTALL) # 用于获取动态值中的变量表达式
  6. REGEX_PATTERN_FOR_FUNC_DEFINITION = re.compile('\${\s*__.+?\(.*?\)\s*}', re.DOTALL) # 用于获取函数表达式中的函数名称及其参数
  7. REGEX_PATTERN_FOR_FUNC_NAME_WITH_ARGS = re.compile('\${\s*(__.+?)\((.*?)\)\s*}', re.DOTALL) # 用于获取函数表达式中的函数名称及其参数
  8. def test_func1():
  9.     print('-----func1 called-----')
  10. def test_func2(arg1, arg2):
  11.     print('-----func2 called-----')
  12.     print('arg1:', arg1, 'arg2:', arg2)
  13.     print()
  14.     return "func2"
  15. def test_func3(arg1, arg2):
  16.     print('-----func3 called-----')
  17.     print('arg1:', arg1, 'arg2:', arg2)
  18.     print()
  19.     return 999
  20. def test_func4(arg1, arg2):
  21.     print('-----func4 called-----')
  22.     print('arg1:', arg1, 'arg2:', arg2)
  23.     print()
  24.     return 9.99
  25. def test_func5(arg1, arg2):
  26.     print('-----func5 called-----')
  27.     print('arg1:', arg1, 'arg2:', arg2)
  28.     print()
  29.     return ['e1', 'e2']
  30. def test_func6(arg1, arg2):
  31.     print('-----func6 called-----')
  32.     print('arg1:', arg1, 'arg2:', arg2)
  33.     print()
  34.     return False
  35. def test_func7(*args, **kwargs):
  36.     print('-----func7 called-----')
  37.     for i, arg in enumerate(args):
  38.         print('arg%s = %s' % (i, arg))
  39.     for i, kwargs in enumerate(kwargs):
  40.         print('kwarg%s = ' % i, kwargs)
  41. user_name = 'shouke'
  42. addr = 'unknown'
  43. int_var = 3
  44. def evaluate_dynamic_value(dynamic_value):
  45.     '''解析动态值
  46.     @params: dynamic_value 动态值,如果是字符串类型,带双引号、单引号
  47.     '''
  48.     if REGEX_PATTERN_FOR_VAR.search(dynamic_value):
  49.         pattern = REGEX_PATTERN_FOR_VAR
  50.     elif REGEX_PATTERN_FOR_FUNC_DEFINITION.search(dynamic_value):
  51.         pattern = REGEX_PATTERN_FOR_FUNC_DEFINITION
  52.     else:
  53.         return dynamic_value
  54.     var_express_value = None
  55.     match_res = pattern.findall(dynamic_value)
  56.     for var_express in match_res:
  57.         var_name = var_express[2:-1].strip()
  58.         if var_name.startswith('__'): # 函数
  59.             function_mateched = REGEX_PATTERN_FOR_FUNC_DEFINITION.findall(var_express)
  60.             for function in function_mateched:
  61.                 func_info_matched = REGEX_PATTERN_FOR_FUNC_NAME_WITH_ARGS.findall(var_express)
  62.                 for func_info in func_info_matched:
  63.                     func_name, func_args = func_info
  64.                     # print('---',func_name, func_args)
  65.                     if REGEX_PATTERN_FOR_DYNAMIC.search(func_args):
  66.                         func_args = evaluate_dynamic_value(func_args)
  67.                     func_value = eval('{func_name}({func_args})'.format(func_name=func_name.lstrip('_'), func_args=func_args))
  68.                     if func_value is None:
  69.                         func_value = ''
  70.                     var_express_value = var_express.replace(function, str(func_value))
  71.         else: # 变量,不支持嵌套,直接取值
  72.             var_express_value = globals().get(var_name, '')
  73.         if var_express_value is not None:
  74.             dynamic_value = dynamic_value.replace(var_express, str(var_express_value))
  75.             if REGEX_PATTERN_FOR_DYNAMIC.search(dynamic_value): # 替换后的动态值,还是可能存在动态值
  76.                 dynamic_value = evaluate_dynamic_value(dynamic_value)
  77.     return dynamic_value
  78. # 测试验证
  79. print(evaluate_dynamic_value('${ user_name }')) # 输出:shouke
  80. print(evaluate_dynamic_value('${ addr }')) # 输出:unknown
  81. print(evaluate_dynamic_value('username:${ user_name } addr:${ addr }')) # 输出:username:shouke addr:unknown
  82. print(evaluate_dynamic_value('${ __test_func1() }'))
  83. #调用输出:
  84. #-----func1 called-----
  85. print(evaluate_dynamic_value('${ __test_func2("user", "shouke") }')) # 输出:func2
  86. #调用输出:
  87. #-----func2 called-----
  88. # arg1: user arg2: shouke
  89. #
  90. print(evaluate_dynamic_value('test_func1 return: ${ __test_func1() }, test_func2 return: ${ __test_func2("user", "shouke") }')) # 输出:test_func1 return: , test_func2 return: func2
  91. # 调用输出:
  92. #-----func1 called-----
  93. #-----func2 called-----
  94. #arg1: user arg2: shouke
  95. #
  96. print(evaluate_dynamic_value('${ __test_func7("addr", "sz") }'))
  97. #-----func7 called-----
  98. #调用输出:
  99. #arg0 = addr
  100. #arg1 = sz
  101. print(evaluate_dynamic_value('${ __test_func7(110,'
  102.                              ' 11.56, '
  103.                              '"test", '
  104.                              '[1, 3, 5], '
  105.                              '["2", "4", "6"], '
  106.                              '1 == 1, '
  107.                              'True, '
  108.                              '{"username": "shouke", "age": "unknown"},'
  109.                              'position="sz",'
  110.                              'hobby="pingpong",'
  111.                              'books=["unkonwn"]) }'))
  112. #调用输出:
  113. # -----func7 called-----
  114. # arg0 = 110
  115. # arg1 = 11.56
  116. # arg2 = test
  117. # arg3 = [1, 3, 5]
  118. # arg4 = ['2', '4', '6']
  119. # arg5 = True
  120. # arg6 = True
  121. # arg7 = {'username': 'shouke', 'age': 'unknown'}
  122. # kwarg0 =  position
  123. # kwarg1 =  hobby
  124. # kwarg2 =  books
  125. print(evaluate_dynamic_value('${ __test_func7("${user_name}", ${int_var})}'))
  126. #调用输出:
  127. #-----func7 called-----
  128. #arg0 = shouke
  129. #arg1 = 3
  130. 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:
  131. #调用输出:
  132. #-----func6 called-----
  133. #arg1: shouke arg2: 3
  134. #
  135. #-----func4 called-----
  136. #arg1: 3 arg2: func4
  137. #
  138. #-----func2 called-----
  139. #arg1: func2 arg2: True
  140. #
  141. #-----func3 called-----
  142. #arg1: func2 arg2: func3
  143. #
  144. #-----func5 called-----
  145. #arg1: 9.99 arg2: 999
  146. #
  147. #-----func7 called-----
  148. #arg0 = False
  149. #arg1 = ['e1', 'e2']
  150. #-----func2 called-----
  151. #arg1: func2 arg2: True
  152. #
  153. #-----func4 called-----
  154. #arg1: 3 arg2: func4
  155. #
  156. #-----func2 called-----
  157. #arg1: func2 arg2: True
  158. #
  159. #-----func2 called-----
  160. #arg1: func2 arg2: True
  161. #
  162. #-----func2 called-----
  163. #arg1: func2 arg2: True
  164. #
  165. #-----func2 called-----
  166. #arg1: func2 arg2: True
  167. #
  168. print(evaluate_dynamic_value('${ __test_func7(set([1, 2, 3]))}'))
  169. #调用输出:
  170. # -----func7 called-----
  171. # arg0 = {1, 2, 3}
复制代码
来源:https://www.cnblogs.com/shouke/p/17843050.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具