这是一个有趣的。任何人都有一个很好的RegEx将所有(第一个)^(第二个)转换为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帮助您在制作时正确显示正则表达式。这就是我一直在做的事情。
答案 0 :(得分:11)
使用正则表达式无法做到这一点(至少不需要付出很多努力)。您必须考虑括号的不同层,无法使用简单的正则表达式处理。我建议寻找一个能够解析数学表达式的库。或者你必须将可能的表达式限制为你可以使用简单的正则表达式处理的东西。
可以在正则表达式中定义命名和平衡捕获组,可以在同一个正则表达式中使用(反向引用)。有了这个,你必须定义数学语法的所需子集和两个参数的捕获。我建议你不要重新发明轮子并使用JS库。
答案 1 :(得分:2)
您可以使用String.replace
:
> s = "hello 2^3 pow!"
> s.replace(/(\d+)\^(\d+)/, "Math.pow($1, $2)")
"hello Math.pow(2, 3) pow!"
答案 2 :(得分:1)
假设您要转换源文件或类似内容,请在源文件上运行perl脚本并使用Math::Expression::Evaluator::Parser。从概要:
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中实现一个计算器,那么你当然需要JavaScript-Parser,或者你可以依赖使用Math :: Expression :: Evaluator实现的服务器后端。
答案 3 :(得分:1)
坏消息:正则表达式不会削减它(正如许多答案所示),你需要为此编写一个解析器。
好消息:通过编写递归下降解析器,您可以相对轻松地以几乎任何语言自己完成此操作。您当然应该尽可能地重用现有代码,但是自己编写递归下降解析器(以及查看编码优先级规则的方式)可以纯粹用于启发性体验。
拿起任何关于编译器构造的书,阅读前几章有关解析的内容。让我推荐Niklaus Wirth的this freely available book,寻找4.1“递归下降的方法”。
答案 4 :(得分:1)
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;
};
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
替换为您想要的任何功能名称。
我通过使用非数学文本(___joker___0
,___joker___1
等替换所有括号,从最内部到最外部,完成此操作。最后,我将分层次地解析所有这些字符串,以替换非括号表达式上的插入符号。
答案 5 :(得分:0)
看看Jison,一个Javascript解析器生成器。
特别要查看他们的calculator demo