Вы можете использовать re.sub
:
import re
strip_f = lambda f: (f.split("(")[0], f.split("(")[1][:-1].split(", "))
def explicit(expr, functions):
d = {}
for f in functions:
func_vars, func_def = f.split(" = ")
func_name, func_vars = strip_f(func_vars)
d[func_name] = (func_vars, func_def)
def replace(match):
m = match.groups()[0]
fn_name, expr_vars = strip_f(m)
func_vars, s = d[fn_name]
for fv, ev in zip(func_vars, expr_vars):
s = s.replace(fv, "("+ev+")")
s = "("+s+")"
return s
return re.sub(r"(.\(([^\)]+,?)+?\))", replace, expr)
expr = '2*a*b + f(b+a, 2*b) + g(5, 2*c, 3+a)'
f1 = "f(x, y) = x + 2*y + 3"
f2 = "g(x, y, z) = x + y + z - 2"
print(explicit(expr, [f1, f2]))
Дисплеи:
2*a*b + ((b+a) + 2*(2*b) + 3) + ((5) + (2*c) + (3+a) - 2)
Регулярное выражение с разбивкой:
( begin capturing group for function
. match any character (function nname)
\( match open parenthesis
( begin capturing group for variable
[^\)]+ match at least one non-parenthesis character
,? match a comma if it's there
) end variable capturing
+? match at least one variable
\) match close parenthesis
) end capturing group
Если вы неЕсли вы упростите вывод, вы можете использовать sympy
методы, которые вы упомянули:
import sympy
expr = '2*a*b + f(b+a, 2*b) + g(5, 2*c, 3+a)'
f1 = "f(x, y) = x + 2*y + 3"
f2 = "g(x, y, z) = x + y + z - 2"
def split(fn):
return str(fn).partition("(")
def check_fn(ex):
name, sep, rest = split(ex)
return name and sep
def parse_functions(functions):
fns = {}
for f in functions:
name, _, rest = split(f)
fn = rest.split(" = ")
fns[name] = fn[0][:-1].split(", "), fn[1]
return fns
def expand(expr, functions):
fns = parse_functions(functions)
def sub_fn(ex):
with sympy.evaluate(False):
vs, fn = fns[split(ex)[0]]
fn = sympy.UnevaluatedExpr(sympy.sympify(fn))
return fn.subs(dict(zip(vs, str(ex)[2:-1].split(", "))))
return sympy.sympify(expr).replace(check_fn, sub_fn)
print(sympy.StrPrinter({'order':'none'})._print(expand(expr, [f1, f2])))
Отображение:
2*a*b + a + b + 2*(2*b) + 3 + 5 + 2*c + a + 3 - 2
Обратите внимание, что это предполагает, что вы хотите полный,неупорядоченное неупорядоченное уравнение.