【问题标题】:Replace var^power with pow(var,power)用 pow(var,power) 替换 var^power
【发布时间】:2014-11-22 05:52:36
【问题描述】:

我正在用 Java 编写一个数学应用程序,它使用 Javascript 进行脚本/输入。 我希望能够输入 x^2 并让 Java 在发送到 JavaScript 解析器之前将其替换为 pow(x,2)。我该如何进行这种类型的替换?在一个代码 sn-p 中可能有多个不同的此类表达式,可能是一行或多行。

【问题讨论】:

  • Java 和 JavaScript 是不同的语言,除了它们都继承自 C 的一些语法外,几乎没有任何共同之处。不要混淆它们。
  • @cdhowie 我不是。我的 Java 应用程序使用 JavaScript 解析器 (javax.script.ScriptEngine) 来评估 JavaScript 中输入的表达式。
  • 您需要考虑关联性和优先级 - 因此您需要编写一个解析器。
  • 我不确定这个应用程序是干什么用的,但如果你有机会处理更复杂的表达式,包括带括号的表达式,我不会从正则表达式路径开始,除了也许如果您需要一个简单的演示原型。你可能最终只会让正则表达式变得越来越复杂,然后不得不把整个事情都扔掉。
  • 不能用正则表达式可靠地做到这一点。它根本不够强大。你需要一个真正的数学解析器。请参阅:Evaluating a math expression given in string form

标签: java javascript regex string


【解决方案1】:

您应该派生 esprima JS 解析器以添加具有适当优先级的 ^ 运算符等。然后遍历解析树,确定它的使用位置,并进行词法替换。此链接可能有用:http://ariya.ofilabs.com/2011/08/math-evaluator-in-javascript-part-2.html。不太确定如何从 Java 程序中调用它,但我相信你可以弄清楚。

或者,http://mathjs.org/ 中的解析器显然已经支持^,所以你可以使用它。或者,http://silentmatt.com/javascript-expression-evaluator/ 似乎也支持^。或者http://jsep.from.so/,“一个小小的 JavaScript 表达式解析器”。

相关SO问题:Safe evaluation of arithmetic expressions in Javascript

【讨论】:

    【解决方案2】:

    更新:

    我不确定您期望有多少复杂性,但如果您希望它能够处理一些棘手的表达式,您不妨使用解析器库。


    假设您正在谈论 javascript 并且您正在替换字符串输入,请执行以下操作。

    "x^2".replace(/(.*)\^(\d+)/, "pow($1, $2)")
    

    【讨论】:

    • 我会在你的 RegExp 中添加更多上下文来处理空格、否定等。
    • 如果a^b 出现在字符串文字中怎么办?
    • 如果用户输入更复杂的东西,比如x^0.5(x+y)^(z-4)怎么办? (甚至x^y^2。)
    • @dandavis 是的,我敢打赌他们的正则表达式和埃及象形文字一样具有可读性...... :) :) :)
    • @dandavis tl;dr 版本是“可以”和“应该”是不同的东西。你能用正则表达式做到这一点吗?也许,但不太可能。你应该。不。见鬼,不。
    【解决方案3】:

    试试这个: 更新:在某些情况下是可能的

    var re = /(?![\+\-\*\/\(\)\^\s])([a-zA-Z0-9]+)\^([a-zA-Z0-9]+)/gm;
    var str = 'w*x^2 +5^9';
    var subst = 'pow($1,$2)';
    
    var result = str.replace(re, subst);
    

    live demo

    以及更好的数学计算参考.http://mathjs.org/

    示例和输出

    // expressions
    math.eval('1.2 * (2 + 4.5)');     // 7.8
    math.eval('5.08 cm to inch');     // 2 inch
    math.eval('sin(45 deg) ^ 2');     // 0.5
    math.eval('9 / 3 + 2i');          // 3 + 2i
    math.eval('det([-1, 2; 3, 1])');  // -7
    

    【讨论】:

    • 如果输入是y^3 + x^2怎么办?问题是“在一个代码 sn-p 中可能有多个不同的此类表达式”。
    • 而 32*x^2 应该变成 32*pow(x,2),而不是 pow(32*x,2)。
    • a^(b^c)(a^b)^c 怎么样?祝你好运,只用正则表达式就可以正确地进行这些替换。
    • @AhosanKarimAsik 提示:你不能。正则表达式不会那样递归。它无法解析常规语言。
    • @AhosanKarimAsik 跟着我慢慢重复:你不能用正则表达式解析表达式。对于你提出的每一个有效的案例,我都可以很容易地提出一个无效的反例。这是解析理论 101。
    猜你喜欢
    • 2021-01-11
    • 2020-07-05
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多