5

Python 实现简单的数学表达式解析并处理

 8 months ago
source link: https://www.lfhacks.com/tech/python-expression-parser/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Python 实现简单的数学表达式解析并处理

2023-12-27
标签: PYTHON
3797.jpg
扫一扫,转发文章 python-expression-parser.png

对于任意深度的数学表达式,希望使用 Python 解析,然后按照某种规则处理其中的元素。这里最终结果只是对单个元素的字面处理,而没有涉及表达式的表示和运算。

任意数学表达式,包含数字、变量、四则运算符、函数名称、括号等符号,比如下面的例子:

A * (B + 3) / SUM(C+D)

我们希望按照任意的规则去处理其中的某些类型的符号,比如:

  • 去掉函数名称,得到 A*(B+3)/(C+D)
  • 替换变量,得到 AA*(BB+3)/SUM(CC+DD)

分词-Tokenize

首先我们需要设计一个函数把表达式的每个符号分隔开,并且根据字面量的值来判断所属的类型,跟我们人类观察的方法完全一样。比如下面的表达式

A * (B + 3) / SUM(C+D)

我们从左往右观察的时候,心里会想:

A → 字母 → 变量 空格 → 忽略 → 忽略 * → 属于[+-*/]中的一种 → 运算符 ( → 属于[()]中的一种 → 括号 B → 字母 → 变量 ….以此类推

那么需要设计一个 tokenize() 函数,将原始表达式逐个按照字符的字面量划分类型。同时,将这个函数设计为生成器,使代码更简洁高效。代码如下:

def tokenize(s): toks = re.compile(r' +|[\d\.]+|[A-Za-z_0-9]+|[\(\)]|[\+\-\*\/]') for match in toks.finditer(s): s = match.group(0) if s[0] == ' ': continue elif s[0] in '()': yield (s, s) elif s[0].isdigit(): yield ('NUMBER', s) elif s[0].isalpha(): yield ('FUNC', s) elif s[0] == '[': yield ('COUNTER', s) elif s[0] in '+-*/': yield ('OPER', s) else: yield ('OTHER', s)

下面看看这个函数的运行过程:

首先创建的正则表达式,用多个 | 或符号分隔多种情况,包括:空格( +)、带小数点的数字([\d\.]+)、字母数字混合([A-Za-z_0-9]+)、小括号([\(\)])、四则运算符([\+\-\*\/]

finditer()返回一个迭代器,每次迭代返回的内容是一个 Match Object,Match Object 的 group() 函数返回分组的结果,参数为 0 时,返回完整的匹配结果。

接下来根据匹配内容的第一个字符来判断所属的类型:

如果您对本站内容有疑问或者寻求合作,欢迎 联系邮箱 。邮箱已到剪贴板

标签: PYTHON

欢迎转载本文,惟请保留 原文出处 ,且不得用于商业用途。
本站 是个人网站,若无特别说明,所刊文章均为原创,并采用 署名协议 CC-BY-NC 授权。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK