** IE11 不支持运算符。如何使用代码将其替换为Math.pow?

2024-03-17

我有这个示例公式:

((97000 * ((5.50/100)/12)) / (1 - ((1 + ((5.50/100)/12))**(-1 * 120))))

问题是此代码在 IE11 中无法正常工作。我尝试过这种方法来替换每个** with Math.pow,但我无法让它正常工作:

function detectAndFixTrivialPow(expressionString) {
  var pattern = /(\w+)\*\*(\w+)/i;
  var fixed = expressionString.replace(pattern, 'Math.pow($1,$2)');
  return fixed;
}

var expr = "((97000 * ((5.50/100)/12)) / (1 - ((1 + ((5.50/100)/12))**(-1 * 120))))";
var expr2 = detectAndFixTrivialPow(expr);

console.log(expr);
console.log(expr2); // no change...

用正则表达式尝试这个将会很困难。相反,请使用转译器或至少是 ECMAScript 解析器。

以下是如何使用 esprima 解析器完成此操作的示例。该 API 生成一棵 AST 树。下面的代码寻找**该树中的运算符并收集输入字符串应更改的偏移量。然后这些偏移量按降序排序,以便将它们按正确的顺序应用到输入字符串。

请注意,此代码不会尝试保存任何括号。输入中的那些将被保留,并为每个添加一个额外的对Math.pow calls.

function convert(input) {
    let modifs = [];
    
    function recur(ast) {
        if (Object(ast) !== ast) return; // not an object
        if (ast.type === "BinaryExpression" && ast.operator == "**") {
            modifs.push(
                [ast.range[0], 0, "Math.pow("], 
                [input.indexOf("**", ast.left.range[1]), 2, ","],
                [ast.range[1], 0, ")"]
            );
        }
        Object.values(ast).forEach(recur);
    }
    recur(esprima.parse(expr, { range: true }));
    
    modifs.sort(([a], [b]) => b - a);
    
    let output = [...input];
    for (let params of modifs) output.splice(...params);
    return output.join("");
}

// Demo
let expr = "((97000 * ((5.50/100)/12)) / (1 - ((1 + ((5.50/100)/12))**(-1 * 120))))"

let result = convert(expr);
console.log(result);
<script src="https://cdn.jsdelivr.net/npm/[email protected] /cdn-cgi/l/email-protection/dist/esprima.min.js"></script>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

** IE11 不支持运算符。如何使用代码将其替换为Math.pow? 的相关文章

随机推荐