如何按运算符拆分数学字符串并保留匹配括号内的内容
问题:拆分数学表达式为包含匹配括号块的列表
需求:将任意数学字符串按+、-、*、/运算符拆分为列表,同时将匹配括号内的所有内容(包括嵌套括号、字母如π等)作为单个列表元素。
示例:
import math # 示例1:无括号表达式 equation = "5+5*10" equation_segmented = ["5", "+", "5", "*", "10"] # 示例2:含嵌套函数的表达式 equation = "(2*2)-5*(math.sqrt(9)+2)" equation_segmented = ["(2*2)", "-", "5", "*", "(math.sqrt(9)+2)"] # 示例3:多层嵌套括号表达式 equation = "(((5-3)/2)*0.5)+((2*2))*(((math.log(5)+2)-2))" equation_segmented = ["(((5-3)/2)*0.5)", "+", "((2*2))", "*", "(((math.log(5)+2)-2))"]
已尝试的方法:
- 使用正则表达式
re.split("([\+|\-|\*|\/]|\(.*\))", equation):无法处理嵌套匹配括号,会错误匹配从第一个(到最后一个)的全部内容。 - 手动遍历字符串并跟踪括号计数器:未成功实现正确逻辑。
- 先按运算符拆分再合并括号内元素:未实现正确的括号内元素合并逻辑。
不确定是否需要解析器,寻求可行解决方案。
解决方案:手动遍历+括号深度跟踪
正则表达式无法处理嵌套括号的匹配,手动遍历+括号深度跟踪是最可靠的方案,具体实现如下:
def split_math_expression(equation): segments = [] current_segment = [] bracket_depth = 0 for char in equation: # 遇到括号时更新深度 if char == '(': bracket_depth += 1 current_segment.append(char) elif char == ')': bracket_depth -= 1 current_segment.append(char) # 仅在括号外时,处理运算符分割 elif bracket_depth == 0 and char in '+-*/': # 存入当前累积的非空片段 if current_segment: segments.append(''.join(current_segment).strip()) current_segment = [] # 运算符单独作为列表元素 segments.append(char) else: current_segment.append(char) # 处理最后一个未存入的片段 if current_segment: segments.append(''.join(current_segment).strip()) # 过滤空字符串(处理首尾空格或无效空片段) return [seg for seg in segments if seg] # 测试示例 import math test_cases = [ "5+5*10", "(2*2)-5*(math.sqrt(9)+2)", "(((5-3)/2)*0.5)+((2*2))*(((math.log(5)+2)-2))", "π*(3+2)-(math.sin(π/2)+1)" # 含π的测试用例 ] for eq in test_cases: result = split_math_expression(eq) print(f"原表达式:{eq}") print(f"拆分结果:{result}\n")
逻辑说明:
- 括号深度跟踪:用
bracket_depth记录当前所处的括号层级,遇到(深度+1,遇到)深度-1。 - 片段累积:用
current_segment列表实时累积当前正在构建的片段内容。 - 分割触发:只有当括号深度为0(处于括号外)时,遇到
+-*/才会将当前片段存入结果,并将运算符单独作为元素存入。 - 收尾处理:遍历结束后存入最后一个片段,并过滤空字符串,避免无效元素。
该方法能完美处理嵌套括号、含特殊符号/字母的表达式,逻辑清晰易维护,无需复杂解析器。
内容的提问来源于stack exchange,提问作者Dean
相关产品推荐
相关产品推荐

