我正在尝试在Javascript中创建类似eval()的函数(从字符串计算表达式)。 我在连续' - '操作中遇到错误。 除了' - '一切都很好。 任何人都可以帮助我让' - '工作 用于实时预览codepen link- https://codepen.io/raj1998211/pen/yvVXLd
function mat(str){
// var sum = 0;
ns = str;
while(ns.indexOf('/') > 0){
var regex = /(\d+|(\d+\.\d+))(\/)((\d+\.\d+)|\d+)/g;
var ns = ns.replace(regex, function(a){
arr = a.split("/");
ans = Number(arr[0]) / Number(arr[1]);
return ans;
});
// console.log(ns);
}
while(ns.indexOf('*') > 0){
var regex = /(\d+|(\d+\.\d+))(\*)((\d+\.\d+)|\d+)/g;
var ns = ns.replace(regex, function(a){
arr = a.split("*");
ans = Number(arr[0]) * Number(arr[1]);
return ans;
});
// str = ns;
// console.log(ns);
}
while(ns.indexOf('-') > 0){
var regex = /(\-\d+|\d+|(\d+\.\d+))(\-)((\d+\.\d+)|\d+)/g;
var ns = ns.replace(regex, function(a){
arr = a.split("-");
ans = Number(arr[0]) - Number(arr[1]);
return Math.abs(ans);
// return ans;
});
// console.log(ns);
}
// if(ns.indexOf('-') === 0){
// }
if(ns.indexOf('+') > 0){
arr = ns.split("+");
sum = 0;
for(i = 0; i < arr.length; i++){
sum += Number(arr[i]);
}
ns = sum;
}
// return "sum";
return ns;
}
console.log(mat("4-5-1")); //infinite loop if '-' comes on first char of str
答案 0 :(得分:0)
您应该考虑这是否按预期工作,因为任何负数都会破坏您的代码。 (例如:mat(&#34; 1 + -1&#34;))。考虑正则表达式是否具有解析表达式所需的表达能力,因为它们非常有限。 (例如,您不能仅使用正则表达式检查平衡括号)
你可能想要研究解析,网上有很多教程描述这个。
您可能还想查找常规语言的限制(正则表达式可以表达/&#34;解析&#34;)
下一步可能是研究所谓的&#34;无上下文语法&#34;,它具有更强的表达能力。
对于完整的解析,一些有用的关键字是&#34; Tokenizing&#34;和#34;抽象语法树&#34;。希望其中一些可以帮助您研究您的需求。
答案 1 :(得分:0)
问题是4-5产生-1,所以在第一次替换后你得到
-1-1
,导致infinte循环,或者,abs()
hack
1-1
,导致错误的结果。
一种选择是删除abs()
黑客并使用ns.indexOf('-', 1)
,但这可能会导致数字出现负数问题 - 并且您的数字正则表达式似乎无法解决负数也是......所以你也需要解决这个问题。
解决此问题的一个选择可能是:
或者,你可以使用像这样的递归方法而不是你的术语重写方法:
function mat(str) {
var operators = "/*-+";
for (var i = 0; i < 4; i++) {
var op = operators.charAt(i);
var pos = str.indexOf(op);
if (pos > 0 && operators.indexOf(str.charAt(pos - 1)) == -1) {
var left = mat(str.substr(0, pos));
var right = mat(str.substr(pos + 1));
switch (op) {
case "/": return left / right;
case "*": return left * right;
case "-": return left - right;
case "+": return left + right;
}
}
}
return Number(str);
}