【问题标题】:Using Python's Regular Expression to Insert Symbol Between Certain Characters使用 Python 的正则表达式在某些字符之间插入符号
【发布时间】:2015-09-25 06:36:40
【问题描述】:

我正在制作一个数学程序,允许用户输入一个方程,程序会解决它。我正在努力使其尽可能用户友好。我希望用户能够轻松地输入方程,而不必担心在每个乘法实例之间添加乘法符号。

这是一个例子:

用户输入:y=xy+yz 程序输出:y=x*y+y*z

我已经能够使用 Python 的 re 模块轻松完成此操作,如下所示:

equation = "y=xy+yz"
equation = re.sub(r"([xyzuvet])([xyzuvet])",r"\1*\2", equation)  # x,y,z,u,v,e, and t and variables and constants the user can use in their equation.
equation = re.sub(r"([xyzuvet])([xyzuvet])",r"\1*\2", equation)  # Must run twice in the event the equation looks something like y=xyzxyz

但是,当我引入一个特殊的函数(例如y=yexp(x))时,我遇到了一个问题。当我运行上面的代码时,我会得到y=y*e*xp(x)的输出。

我后来更新了我的代码来解释 pi:

equation = re.sub(r"([xyzuve]|pi)([xyzuve]|pi)",r"\1*\2", equation)
equation = re.sub(r"([xyzuve]|pi)([xyzuve]|pi)",r"\1*\2", equation)

我在想我可以使用上面类似的方法来匹配exp 并防止它在“e”和“x”之间添加*,如下所示:

equation = re.sub(r"([xyzuve]|pi|exp)([xyzuve]|pi|exp)",r"\1*\2", equation)
equation = re.sub(r"([xyzuve]|pi|exp)([xyzuve]|pi|exp)",r"\1*\2", equation)

我想通过添加exp 以与我添加pi 相同的方式,它会起作用;但不幸的是它不起作用。有没有办法将exp和其他同时包含x、y、z、u、v、t和e的函数作为一个整体来处理?

以下是一些我希望输入看起来像的示例:

输入:y=eexp(xyz) 输出:y=e*exp(x*y*z)

输入:y=pifrexp(yt) 输出:y=pi*frexp(y*t)

输入:y=sin(x)exp(y) 输出:y=sin(x)*exp(y)

【问题讨论】:

  • exppi放在第一位。
  • 我刚刚尝试过,不幸的是出现了同样的问题。
  • 因为re.sub第二次了。

标签: python regex replace insert


【解决方案1】:

这似乎产生了你想要的:

equation = re.sub(r"([)xyzuvet]|pi|exp|frexp)([xyzuvet]|pi|exp|frexp)\b",r"\1*\2", equation)
equation = re.sub(r"([)xyzuvet]|pi|exp|frexp)([xyzuvet]|pi|exp|frexp)\b",r"\1*\2", equation)

例如:

>>> import re
>>> eqns = ('y=eexp(xyz)', 'y=pifrexp(yt)', 'y=sin(x)exp(y)')
>>> for equation in eqns:
...     equation = re.sub(r"([)xyzuvet]|pi|exp|frexp)([xyzuvet]|pi|exp|frexp)\b",r"\1*\2", equation)
...     equation = re.sub(r"([)xyzuvet]|pi|exp|frexp)([xyzuvet]|pi|exp|frexp)\b",r"\1*\2", equation)
...     print equation
... 
y=e*exp(x*y*z)
y=pi*frexp(y*t)
y=sin(x)*exp(y)

【讨论】:

  • 在我尝试y= eexp(xyzzzz) 之前,您的解决方案运行良好。我的输出变为y=e*exp(xyzz*z*z)编辑:如果我多次重复re.sub,它会起作用,但并不是最好的方法。
  • @anubhava 是的,我有。它缺少e,因此在e 和另一个字符之间没有出现*。当我将“e”添加回列表时,会出现同样的问题。
  • 所以pifrexp(yte) 应该变成pi*frexp(y*t*e) ?
  • 当我为pifrexp(yte) 运行(?!^)(?=(?<!fr)(?:fr)?exp|sin|pi|(?<=[txyzuve])[txyzuve]) 时,我得到pi*fre*xp(y*t*e)
【解决方案2】:

您可以使用环顾四周

(?<=[xyzuvtf])(?=[xyzuvtf])|(?=exp)|(?<=pi)

Regex Demo

【讨论】:

  • 不是在frexp中加了*吗?
  • 这是一个很好的观点。 f 不是我的程序中使用的变量,所以没关系,但很好。
【解决方案3】:

这个基于外观的正则表达式适用于您的所有测试用例:

(?!^)(?=(?<!fr)(?:fr)?exp|sin|pi|(?<=[xtyzuv]|e(?!xp))[etxyzuv])

RegEx Demo

【讨论】:

    猜你喜欢
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    相关资源
    最近更新 更多