【发布时间】:2014-06-08 15:06:14
【问题描述】:
我是一名新手程序员,用 JavaScript 为学校项目制作了一个简单的计算器,我没有使用 eval() 来计算字符串,而是创建了自己的函数 calculate(exp)。
基本上,我的程序使用运算顺序(PEMDAS,或括号、指数、乘法/除法、加法/减法)来评估字符串表达式。我的正则表达式模式之一是这样的(“mdi”表示乘法/除法):
mdi = /(-?\d+(\.\d+)?)([\*\/])(-?\d+(\.\d+)?)/g; // line 36 on JSFiddle
这是做什么的:
-?\d+找到一个整数(\.\d+)?匹配小数点(如果有的话)[\*\/]匹配使用的运算符(*或/用于乘法或除法)/g匹配字符串表达式中的每个出现。
我用下面的代码循环这个正则表达式的匹配:
while((res = mdi.exec(exp)) !== null) { // line 69 on JSFiddle
exp = exp.replace(mdi,
function(match,$1,$3,$4,$5) {
if($4 == "*")
return parseFloat($1) * parseFloat($5);
else
return parseFloat($1) / parseFloat($5);
});
exp = exp.replace(doN,""); // this gets rid of double negatives
}
但是,这并不总是有效。它仅适用于绝对值小于 10 的数字。我无法对 24 和 -5232000321 等数字执行任何操作,即使正则表达式应与 + 量词匹配。它适用于小数字,但当数字大于 10 时会崩溃并耗尽我的大部分 CPU。
例如输入5*.5表达式时,输出2.5,但输入75*.5并回车时,程序停止。
我不太确定这里发生了什么,因为由于某种原因我无法找到错误的根源 - 即使我的代码中到处都有 console.log() 进行调试,但我认为它没有任何显示这个正则表达式有问题。发生了什么?
完整的代码(到目前为止)在JSFiddle.net,但请注意它可能会崩溃。如果您有任何其他建议,也请告诉我。
感谢您的帮助。
【问题讨论】:
-
尝试删除 g 标志
-
另外,这是编写计算器解析器的一种非常复杂的方法。如果这就是你正在做的事情。
-
@BenjaminGruenbaum 再说一次,我不是专业人士,我不确定该怎么做。如果您有任何建议,请告诉我。
-
听起来你可能有一个catastrophic backtracking 的案例。考虑到字符串 '123*456' 还包括字符串 '23*456'、'3*456'、'123*45' 和许多其他组合。您需要检测“令牌”(例如多位数字)的开始和结束位置。
-
子模式
\d+(\.\d+)?无法匹配没有前导数字的浮点数,例如.5。
标签: javascript regex match