重写公式字符串以用Math.pow(a,b)替换^ b

pim*_*vdb 3 javascript regex parsing

我现在正试图<canvas>通过让用户输入公式来在HTML5上绘制公式.这很好用eval(); 然而,这^意味着Javascript中的按位XOR,而它应该意味着公式中的"权力".

所以基本上我不得不重写像x^4Math.pow(x, 4).我想出了使用正则表达式.然而,这只在一定程度上起作用:

"x^4".replace(/(.*)\^(.*)/g, "Math.pow($1, $2)")

它改写x^4Math.pow(x, 4),但对于更先进的配方这一出错.例如,2 + x^4被重写为Math.pow(2 + x, 4),而它当然应该是2 + Math.pow(x, 4).此外,如果指数在其周围有括号,例如2^(x+1) + 3,它应该被重写Math.pow(2, x+1) + 3而不是Math.pow(2, x+1 + 3)当然.

我将如何重写这一点,以便只将正确的部分放入pow功能?我真的没有看到从哪里开始,所以任何提示将不胜感激.

Dan*_*umb 7

这是一个棘手的问题.你在这里谈论的是一个表达式解析器.

您可能想看看Jison,它旨在帮助人们解决此类问题.

正则表达式实际上不是解析标记化字符串的最佳方法.一个Jison的演示的正是你在找什么,在表达分析方面,让你对功能图形的有趣的东西工作.


Eri*_*olz 5

    var caretReplace = function(_s) {
    if (_s.indexOf("^") > -1) {
        var tab = [];
        var powfunc="Math.pow";
        var joker = "___joker___";
        while (_s.indexOf("(") > -1) {
            _s = _s.replace(/(\([^\(\)]*\))/g, function(m, t) {
                tab.push(t);
                return (joker + (tab.length - 1));
            });
        }

        tab.push(_s);
        _s = joker + (tab.length - 1);
        while (_s.indexOf(joker) > -1) {
            _s = _s.replace(new RegExp(joker + "(\\d+)", "g"), function(m, d) {
                return tab[d].replace(/(\w*)\^(\w*)/g, powfunc+"($1,$2)");
            });
        }
    }
    return _s;
};
Run Code Online (Sandbox Code Playgroud)
  1. console.log(caretReplace("(3*(f(x^2)-2)^2+1^5-g(2^3+1)^5)^(9-2^3)")); 给出:Math.pow((3*Math.pow((f(Math.pow(x,2))-2),2)+Math.pow(1,5)-Math.pow(g(Math.pow) (2,3)+1),5)),(9-Math.pow(2,3)))

  2. 您的数学表达式必须具有良好平衡的左括号和右括号(有效表达式)。

  3. 您可以将“Math.pow”替换为您想要的任何函数名称。

  4. 我通过用非数学文本(“ _joker _0”、“ _joker _1”等)替换所有括号(从最内层到最外层)来完成此操作。最后,我分层解析所有这些字符串,以替换非括号表达式上的插入符。