Python如何将包含数学运算符的字符串转换为可计算的表达式?
字符串格式数学表达式转可计算结果的实现方案
核心安全提醒
绝对不要直接调用各语言内置的eval类方法处理未校验的用户输入,会触发任意代码执行漏洞,存在严重安全风险。
实现思路
主流有两种安全实现路径:
- 白名单校验+抽象语法树(AST)解析:仅允许预设的运算符、数值参与计算,拦截所有非法操作
- 调用成熟的社区表达式解析库:无需手动实现解析逻辑,适配场景更广泛
常用语言示例
Python 实现
基于AST解析的安全四则运算求值代码,仅支持数字、加减乘除、括号、负数运算:
import ast import operator ALLOWED_OPS = { ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Div: operator.truediv, ast.USub: operator.neg } def safe_eval_math(expr: str): def parse_node(node): if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)): return node.value elif isinstance(node, ast.UnaryOp) and type(node.op) in ALLOWED_OPS: return ALLOWED_OPS[type(node.op)](parse_node(node.operand)) elif isinstance(node, ast.BinOp) and type(node.op) in ALLOWED_OPS: return ALLOWED_OPS[type(node.op)](parse_node(node.left), parse_node(node.right)) raise ValueError("包含不支持的运算逻辑") try: ast_tree = ast.parse(expr, mode='eval').body return parse_node(ast_tree) except SyntaxError: raise ValueError("无效的数学表达式")
调用示例:safe_eval_math("5+5") 返回 10,safe_eval_math("5*(3+2)") 返回 25
JavaScript 实现
基于白名单校验+隔离作用域执行的实现:
function safeEvalMath(expr) { // 白名单校验,仅允许数字、四则运算符、括号、小数点、空格 if (!/^[\d+\-*/().\s]+$/.test(expr)) throw new Error('无效的数学表达式') // 严格模式隔离作用域,避免访问外部上下文 return new Function(`'use strict'; return (${expr})`)() }
注意事项
- 需要扩展支持幂运算、三角函数等复杂逻辑时,仅在白名单中添加对应允许的操作即可,不要随意放开校验规则
- 生产环境优先选择成熟的社区库,比如Python的
simpleeval、JS的math.js内置的表达式解析能力,无需手动重复实现解析逻辑
内容的提问来源于stack exchange,提问作者Yash Sharma
相关产品推荐
相关产品推荐

