我有这个简单的计算器脚本,但它不允许电源^。
function getValues() {
var input = document.getElementById('value').value;
document.getElementById('result').innerHTML = eval(input);
}

<label for="value">Enter: </label><input id="value">
<div id="result">Results</div>
<button onclick="getValues()">Get Results</button>
&#13;
我尝试使用input = input.replace( '^', 'Math.pow(,)');
但我不知道如何在&#39; ^&#39;之前获得价值。并进入括号后。
示例:(1 + 2)^ 3 ^ 3应该给出7,625,597,484,987
答案 0 :(得分:2)
将正则表达式与捕获组一起使用:
input = '3 + 2 ^3';
input = input.replace(/(\d+)\s*\^\s*(\d+)/g, 'Math.pow($1, $2)');
console.log(input);
&#13;
这仅在参数只是数字时才有效。它不会使用子表达式或重复它,如
(1+2)^3^3
这需要编写一个递归下降的解析器,这比我愿意在这里提出答案的工作要多得多。获取有关编译器设计的教科书,以了解如何执行此操作。
答案 1 :(得分:1)
我认为你不能用简单的替换来做到这一点。
如果要解析中缀运算符,可以构建两个堆栈,一个用于符号,另一个用于数字。然后顺序走公式,忽略符号,数字和右括号之外的所有内容。将符号和数字放入堆栈中,但是当遇到关闭的paren时,请使用最后一个符号并将其应用于最后两个数字。 (由Dijkstra发明,我认为)
const formula = '(1+2)^3^3'
const symbols = []
const numbers = []
function apply(n2, n1, s) {
if (s === '^') {
return Math.pow(parseInt(n1, 10), parseInt(n2, 10))
}
return eval(`${n1} ${s} ${n2}`)
}
const applyLast = () => apply(numbers.pop(), numbers.pop(), symbols.pop())
const tokenize = formula => formula.split(/(\d+)|([\^\/\)\(+\-\*])/).filter(t => t !== undefined && t !== '')
const solver = (formula) => {
const tf = tokenize(formula)
for (let l of formula) {
const parsedL = parseInt(l, 10)
if (isNaN(parsedL)) {
if (l === ')') {
numbers.push(applyLast())
continue
} else {
if (~['+', '-', '*', '/', '^'].indexOf(l))
symbols.push(l)
continue
}
}
numbers.push(l)
}
while (symbols.length > 0)
numbers.push(applyLast())
return numbers.pop()
}
console.log(solver(formula))
答案 2 :(得分:0)
将您的输入变为字符串并执行...
{{1}}
仅当您的唯一操作是'^'
时才会这样编辑:编辑后看到示例,这不再有效。
答案 3 :(得分:0)
function getValues() {
var input = document.getElementById('value').value;
// code to make ^ work like Math.pow
input = input.replace( '^', '**');
document.getElementById('result').innerHTML = eval(input);
}
**
运算符可以替换大多数现代浏览器中的Math.pow
函数。每天推出的下一版Safari(v10.1)都支持它。
答案 4 :(得分:0)
正如其他答案所述,你需要一个真正的解析器才能正确解决这个问题。正则表达式将解决简单的情况,但对于嵌套语句,您需要一个递归解析器。对于Javascript,提供此功能的库是peg.js。
在您的情况下,online version中给出的示例可以快速扩展以处理权限:
Expression
= head:Term tail:(_ ("+" / "-") _ Term)* {
var result = head, i;
for (i = 0; i < tail.length; i++) {
if (tail[i][1] === "+") { result += tail[i][3]; }
if (tail[i][1] === "-") { result -= tail[i][3]; }
}
return result;
}
Term
= head:Pow tail:(_ ("*" / "/") _ Pow)* { // Here I replaced Factor with Pow
var result = head, i;
for (i = 0; i < tail.length; i++) {
if (tail[i][1] === "*") { result *= tail[i][3]; }
if (tail[i][1] === "/") { result /= tail[i][3]; }
}
return result;
}
// This is the new part I added
Pow
= head:Factor tail:(_ "^" _ Factor)* {
var result = 1;
for (var i = tail.length - 1; 0 <= i; i--) {
result = Math.pow(tail[i][3], result);
}
return Math.pow(head, result);
}
Factor
= "(" _ expr:Expression _ ")" { return expr; }
/ Integer
Integer "integer"
= [0-9]+ { return parseInt(text(), 10); }
_ "whitespace"
= [ \t\n\r]*
它返回输入字符串7625597484987
的预期输出(1+2)^3^3
。
答案 5 :(得分:0)
以下是此问题的基于Python的版本,使用pyparsing的解决方案:changing ** operator to power function using parsing?