You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解析Python可求值字符串中的自定义运算符并还原表达式

需求说明

我们需要将字符串形式的公式(其中Python运算符&、|、~被替换为AND、OR、NOT,但字符串字面量内的这些词保持不变)还原为合法的Python表达式,最终目标是能直接求值该表达式。

比如输入:

str_formula = "x > 0 AND y < 5 AND 'this AND that' in my_string"

需要还原为:

python_formula = "x > 0 & y < 5 AND 'this AND that' in my_string"

要求实现需支持:

  • 单双引号的字符串字面量
  • 转义引号的复杂场景(如'this AND tha\'t')
  • 同时处理AND→&、OR→|、NOT→~的替换

现有实现方案

循环遍历方案(支持单双引号)

该方案通过逐字符遍历,跟踪是否处于引号内,仅替换引号外的目标运算符,已补充转义引号支持:

formula = 'x > 0 AND y < 5 AND "this AND that" in my_string'

# 替换引号外的"AND"/"OR"/"NOT"为对应运算符
inverted_formula = ''
in_quote = False
current_quote = None
i = 0
while i < len(formula):
    # 处理转义引号:直接复制转义符和目标字符
    if formula[i] == '\\' and i + 1 < len(formula):
        inverted_formula += formula[i:i+2]
        i += 2
        continue
    # 处理引号状态切换
    if formula[i] in ('"', "'"):
        if not in_quote:
            in_quote = True
            current_quote = formula[i]
        elif formula[i] == current_quote:
            in_quote = False
            current_quote = None
        inverted_formula += formula[i]
        i += 1
        continue
    # 替换引号外的目标运算符
    if not in_quote:
        if formula[i:i+3] == "AND":
            inverted_formula += "&"
            i += 3
            continue
        elif formula[i:i+2] == "OR":
            inverted_formula += "|"
            i += 2
            continue
        elif formula[i:i+3] == "NOT":
            inverted_formula += "~"
            i += 3
            continue
    # 复制普通字符
    inverted_formula += formula[i]
    i += 1

print(inverted_formula)

正则方案(仅支持双引号,未处理转义)

该方案通过正向预查匹配引号外的AND,但仅支持双引号,且无法处理转义引号:

import re

pattern = re.compile(r'\bAND\b(?=([^"]*"[^"]*")*[^"]*$)')
inverted_formula = re.sub(pattern, '&', formula)

复杂测试用例

以下是需要支持的复杂场景测试用例:

f = "x > 0 AND y < 5 AND 'this AND tha\'t' in my_string AND 'this AND tha\'t' in my_string"
f2 = 'x > 0 AND y < 5 AND "this AND tha\'t" in my_string AND "this AND tha\'t" in my_string'
f3 = "'this AND tha\'t' in my_string AND 'this AND that' in my_string"

优化思路探讨

利用AST模块

通过AST解析公式字符串,精准区分运算符标识符和字符串内的词,替换后再反编译为Python代码。这种方法天然支持所有合法Python字符串格式:

import ast
import astunparse

class OperatorReplacer(ast.NodeTransformer):
    def visit_Name(self, node):
        if node.id == 'AND':
            return ast.BitAnd()
        elif node.id == 'OR':
            return ast.BitOr()
        elif node.id == 'NOT':
            return ast.Invert()
        return node

def replace_operators(formula_str):
    # 解析为AST
    tree = ast.parse(formula_str, mode='eval')
    # 替换运算符节点
    tree = OperatorReplacer().visit(tree)
    # 反编译为代码字符串
    return astunparse.unparse(tree).strip()

# 测试
test_formula = "x > 0 AND y < 5 AND 'this AND that' in my_string"
print(replace_operators(test_formula))

注:需提前安装astunparse(pip install astunparse),且公式需符合Python表达式结构(除运算符替换外)

变量赋值技巧

通过给AND、OR、NOT赋值为对应运算符,直接执行表达式字符串。此方法无需修改公式,但存在安全风险,仅适用于可信输入:

def evaluate_formula(formula_str, context):
    # 定义运算符别名
    AND = lambda a,b: a & b
    OR = lambda a,b: a | b
    NOT = lambda x: ~x
    # 合并上下文与运算符别名
    exec_context = {**context, 'AND': AND, 'OR': OR, 'NOT': NOT}
    # 执行表达式
    return eval(formula_str, exec_context)

# 测试
context = {'x': 1, 'y': 3, 'my_string': 'this AND that'}
result = evaluate_formula("x > 0 AND y < 5 AND 'this AND that' in my_string", context)
print(result)  # 输出 True

内容的提问来源于stack exchange,提问作者Ziur Olpa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:58:13