Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/451.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript a^b而不是pow(a,b)的正则表达式_Javascript_Regex - Fatal编程技术网

Javascript a^b而不是pow(a,b)的正则表达式

Javascript a^b而不是pow(a,b)的正则表达式,javascript,regex,Javascript,Regex,这是一个有趣的例子。有没有人有一个好的正则表达式可以将所有(第一个)^(第二个)转换为Math.pow((第一个),(第二个)) 编辑: 到目前为止,我所拥有的最好的是 s = s.replace(/((?:\d+\.?\d*)|\w+|\((?:(?:[^\(\)]*(?:\([^\(\)]*\)))*)\))\s*\^\s*((?:\d+\.?\d*)|\w+|\((?:(?:[^\(\)]*(?:\([^\(\)]*\)))*)\))/g, 'Math.pow($1, $2)') // r

这是一个有趣的例子。有没有人有一个好的正则表达式可以将所有(第一个)^(第二个)转换为Math.pow((第一个),(第二个))

编辑:

到目前为止,我所拥有的最好的是

s = s.replace(/((?:\d+\.?\d*)|\w+|\((?:(?:[^\(\)]*(?:\([^\(\)]*\)))*)\))\s*\^\s*((?:\d+\.?\d*)|\w+|\((?:(?:[^\(\)]*(?:\([^\(\)]*\)))*)\))/g, 'Math.pow($1, $2)') // replace expression ^ expression with Math.pow($1, $2)
到目前为止,答案还不够笼统。它们不包括(var1+var2)^2之类的内容,更不用说(var1*(var2+var3))^2了

解决方案必须使用括号


您可以使用strfriend.com帮助可视化您创建的正则表达式。这就是我一直在做的。

您可以使用
字符串。替换

> s = "hello 2^3 pow!"
> s.replace(/(\d+)\^(\d+)/, "Math.pow($1, $2)")
"hello Math.pow(2, 3) pow!"

这不能用正则表达式实现(至少不需要很多努力)。你必须考虑不同的括号,不能用一个简单的正则表达式来处理。我建议寻找一个能够解析数学表达式的库。或者,您必须将可能的表达式限制为可以使用简单正则表达式处理的内容

可以在正则表达式中定义命名和平衡捕获组,该正则表达式可以在同一正则表达式中使用(反向引用)。这样,您就必须定义所需的数学语法子集以及参数的两个捕获。我建议您不要重新发明轮子,而使用JS库


假设您想要转换源文件或类似的东西,请在源文件上运行一个perl脚本并使用。从大纲中:

use Math::Expression::Evaluator::Parser;

my $exp = '2 + a * 4';
my $ast = Math::Expression::Evaluator::Parser::parse($exp, {});
# $ast is now something like this:
# $ast = ['+',
#          2,
#         ['*',
#          ['$', 'a'],
#          4
#         ]
#        ];
看起来它可以轻松处理指数运算。因此,在您的案例中,AST将类似于:

# $ast = ['^',
#         base,
#         exp
#        ];
您可以通过(递归地)重新组合来自“base”和“exp”子树的字符串来构建所需的表达式“Math.pow(base,exp)”


如果您想在JavaScript中实现计算器,那么您当然需要一个计算器,或者您可以依赖使用Math::Expression::Evaluator实现的服务器后端。

坏消息是:正则表达式无法解决它(正如许多答案所示),您需要为此编写一个解析器

好消息是:通过编写递归下降解析器,您可以相对轻松地在几乎任何语言中实现这一点。当然,您应该尽可能多地重用现有代码,但是您自己编写递归下降解析器(并了解如何编码优先规则)纯粹是为了获得启发性的体验


拿起任何一本关于编译器构造的书,阅读关于解析的前几章。让我推荐Niklaus Wirth的4.1“递归下降的方法”。

看看Jison,一个Javascript解析器生成器

特别是,查看他们的

  • 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))

  • 您的数学表达式必须是有效的,具有平衡的开括号和闭括号

  • 您可以用所需的任何函数名替换
    Math.pow

  • 我用非数学文本替换了所有括号,从最里面到最外面(
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu0
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 1
    ,等等)。最后,我按层次分析所有这些字符串,以替换非括号表达式上的插入符号


  • 你现在最接近的是…?
    a*b^c
    应该转换成什么<代码>a^b+c
    <代码>a^b^c
    ?这不能用普通正则表达式完成。它需要任意递归。如果你想要一个答案,我建议你提高悬赏,这是一个相当复杂的问题。你需要的是一个词法表达式解析器…已经有一段时间了,但我相信匹配任意括号/引号/聊天符通常不属于常规语言,因此不能被常规表达式解析;如果你有一种像parens这样的嵌套结构的语言,那么一种常规语言就不会切割它——事实上,它存在于“常规语言”的定义中。最好开始编写解析器,或者从众多解析器中找到一个。是死的,你能更新吗?这或者一个讨论在JS中实现类似功能的答案是正确的。如果你匹配模式中的可选括号,你可以通过删除多余的括号来增强它。
    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;
    };