解析Excel样式公式

2024-10-01 11:26:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用python从电子表格xml构建公式引用映射。公式就像

=IF(AND(LEN(R[-2]C[-1])>0,R[-1]C),WriteCurve(OFFSET(R16C6, 0,0,R9C7,R10C7),R15C6,R10C3, R8C3),"NONE")

我只想得到writecurve函数的第n个参数。在这里,我提出了一个非常C风格的程序,它基本上是在计算昏迷,它不在括号内。有很多嵌套公式

^{pr2}$

有Python的方法吗?或者有更好的递归方法来解析整个公式吗?非常感谢


Tags: and方法lenifxmloffset公式电子表格
1条回答
网友
1楼 · 发布于 2024-10-01 11:26:04

我所知道的最好的Excel公式解析器是E. W. Bachtal's algorithm。robinmacharg提供了一个Python端口;我知道的最新版本是pycel project的一部分,但它可以独立使用tokenizer。解析公式没有问题:

from tokenizer import shunting_yard
rpn = shunting_yard('=IF(AND(LEN(R[-2]C[-1])>0,R[-1]C),WriteCurve(OFFSET(R16C6, 0,0,R9C7,R10C7),R15C6,R10C3, R8C3),"NONE")')
print(rpn)
deque([<tokenizer.RangeNode object at 0x2b7b1f5d7850>, <tokenizer.FunctionNode object at 0x2b7b1f5d7950>, <tokenizer.ASTNode object at 0x2b7b1f5d7990>, <tokenizer.ASTNode object at 0x2b7b1f5d79d0>, <tokenizer.RangeNode object at 0x2b7b1f5d7a10>, <tokenizer.FunctionNode object at 0x2b7b1f5d7a50>, <tokenizer.RangeNode object at 0x2b7b1f5d7a90>, <tokenizer.ASTNode object at 0x2b7b1f5d7ad0>, <tokenizer.ASTNode object at 0x2b7b1f5d7b10>, <tokenizer.RangeNode object at 0x2b7b1f5d7b50>, <tokenizer.RangeNode object at 0x2b7b1f5d7b90>, <tokenizer.FunctionNode object at 0x2b7b1f5d7bd0>, <tokenizer.RangeNode object at 0x2b7b1f5d7c10>, <tokenizer.RangeNode object at 0x2b7b22efc450>, <tokenizer.RangeNode object at 0x2b7b22efc510>, <tokenizer.FunctionNode object at 0x2b7b22efc410>, <tokenizer.ASTNode object at 0x2b7b22eff110>, <tokenizer.FunctionNode object at 0x2b7b22eff150>])

标记器留给您一个RPN堆栈;如果您发现使用AST更方便,您可以轻松地将其转换为AST:

^{pr2}$

然后,可以遍历AST以找到WriteCurve节点并检查其参数:

def walk(ast):
    yield ast
    for arg in getattr(ast, 'args', []):
        for node in walk(arg):
            yield node

write_curve = next(node for node in walk(rpn_to_ast(rpn)) if node.token.ttype == 'function' and node.token.tvalue == 'WriteCurve')
print(write_curve.args[2].token.tvalue)
R10C3

相关问题 更多 >