如何实现类似Ruby %W[...]操作符的Python模板字符串拆分功能?
实现自定义模板字符串解析与拆分函数
核心思路
要实现需求中的功能,需完成三个关键步骤:
- 解析模板字符串,分离普通字面量和
{}包裹的表达式片段 - 执行表达式求值,获取对应字符串结果
- 合并相邻非空白分隔的片段,最后按空白字符拆分得到目标数组
代码实现
以下是可直接运行的完整代码:
import re from inspect import currentframe def t(s): # 仅作为模板标记,实际解析逻辑在args函数中处理 return s def args(template_str): # 获取调用者的局部与全局变量上下文 caller_frame = currentframe().f_back local_vars = caller_frame.f_locals global_vars = caller_frame.f_globals # 正则匹配:捕获普通字面量、{...}表达式、空白字符 pattern = re.compile(r'(.*?)(\{(.+?)\})|(\s+)') parts = [] current_part = "" for match in pattern.finditer(template_str): literal = match.group(1) expr_match = match.group(2) expr = match.group(3) whitespace = match.group(4) if literal: current_part += literal if expr_match: # 执行表达式求值,模拟f-string的解析逻辑 try: expr_result = eval(expr, global_vars, local_vars) current_part += str(expr_result) except Exception: # 表达式执行出错时保留原内容 current_part += expr_match if whitespace: if current_part: parts.append(current_part) current_part = "" # 处理最后一段非空白内容 if current_part.strip(): parts.append(current_part.strip()) return parts # 测试示例 my_var = "test" print(args(t"foo bar ")) # ["foo", "bar"] print(args(t"{my_var} bar")) # ["test", "bar"] print(args(t"foo/{my_var}{my_var} bar")) # ["foo/testtest", "bar"] print(args(t"foo/{1 + 1} bar")) # ["foo/2", "bar"]
代码说明
- 标记函数
t:仅作为模板字符串的标识,方便args函数识别处理目标字符串,本身不做任何转换操作。 - 上下文变量获取:通过
inspect.currentframe()获取调用者的变量上下文,确保表达式能访问到调用处的局部和全局变量(比如示例中的my_var)。 - 正则解析逻辑:用正则表达式拆分模板字符串,区分字面量、表达式和空白字符,将相邻的字面量与表达式求值结果拼接,遇到空白时将当前拼接内容存入结果列表。
- 表达式求值:使用
eval执行{}内的表达式,实现类似f-string的变量和表达式解析能力。
注意事项
- 该实现未处理转义字符,符合需求中“无需考虑转义字符”的要求。
- 使用
eval存在安全风险,若模板字符串来自不可信来源,建议改用ast模块实现更安全的表达式解析。 - 连续空白和首尾空白会被自动忽略,仅保留非空白的合并片段。
内容的提问来源于stack exchange,提问作者meisel
相关产品推荐
相关产品推荐

