特定场景下如何安全移除公式字符串中值为0的extravariable及关联运算符
实现方案
核心处理逻辑
因为变量固定为0,所以可以结合四则运算规则+正则匹配按优先级处理,避免硬替换导致的语法错误,优先级从高到低依次为Pow函数、乘除运算、加减运算、括号冗余清理。
分步处理规则
- Pow函数场景处理
优先处理函数内的变量,避免后续运算符匹配破坏函数结构:- 匹配
Pow(extravariable, y)直接替换为0 - 匹配
Pow(x, extravariable)直接替换为1 - 如果出现除以
extravariable的场景直接抛出错误,避免非法运算
- 匹配
- 乘除级运算处理
乘除优先级高于加减,优先处理变量和相邻乘除运算符的绑定:- 匹配
extravariable * 变量/变量 * extravariable/extravariable / 变量,直接移除extravariable和相邻的乘除运算符
- 匹配
- 加减级运算处理
加0/减0不影响结果,直接移除变量和关联的加减运算符:- 变量在开头:移除
extravariable和后续相邻的加减运算符 - 变量在结尾:移除
extravariable和前面相邻的加减运算符 - 变量在中间:移除
extravariable和靠后的加减运算符,保留前面的运算符保证语法正确
- 变量在开头:移除
- 冗余清理
最后清理空括号、连续重复运算符、开头多余的加号等语法冗余即可。
代码实现示例(Python)
import re def remove_zero_var(formula: str, var_name: str = "extravariable") -> str: # 转义变量名避免特殊字符影响正则匹配 escaped_var = re.escape(var_name) # 处理Pow函数场景 formula = re.sub(rf'Pow\({escaped_var}\s*,\s*([^)]+)\)', r'0', formula) formula = re.sub(rf'Pow\(([^,]+)\s*,\s*{escaped_var}\)', r'1', formula) # 校验是否存在除以0的非法操作 if re.search(rf'/[\s\(]*{escaped_var}([\s\)]|$)', formula): raise ValueError("公式存在除以0的非法运算") # 处理乘除级绑定 formula = re.sub(rf'{escaped_var}\s*([*/])\s*', r'', formula) formula = re.sub(rf'\s*([*/])\s*{escaped_var}', r'', formula) # 处理加减级绑定 formula = re.sub(rf'^{escaped_var}\s*([+-])\s*', r'', formula) formula = re.sub(rf'\s*([+-])\s*{escaped_var}$', r'', formula) formula = re.sub(rf'\s*([+-])\s*{escaped_var}\s*([+-])\s*', r'\1', formula) # 冗余清理 formula = re.sub(r'\(\s*\)', r'', formula) formula = re.sub(r'([+\-*/])\s*\1+', r'\1', formula) formula = formula.lstrip('+').strip() # 处理公式全是该变量的极端场景 if not formula: return '0' return formula
测试验证
用你给出的三个示例测试,输出完全和预期匹配:
- 输入:
extravariable * somevariable1 + anothervalue * thirdvalue→ 输出:somevariable1 + anothervalue * thirdvalue - 输入:
somevariable1 + anothervalue * thirdvalue+extravariable→ 输出:somevariable1 + anothervalue * thirdvalue - 输入:
somevariable1 + (extravariable * anothervalue) * thirdvalue→ 输出:somevariable1 + (anothervalue) * thirdvalue
如果需要更高的安全性,可以在替换完成后用公式语法解析器做一次合法性校验,避免极端边界case出错。
内容的提问来源于stack exchange,提问作者Arie
相关产品推荐
相关产品推荐

