#javascript #jquery
#javascript #jquery
Вопрос:
У меня есть этот пример формулы:
((97000 * ((5.50/100)/12)) / (1 - ((1 ((5.50/100)/12))**(-1 * 120))))
Проблема в том, что этот код работает некорректно в IE11. Я пробовал этот метод для замены каждого **
на 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...
Комментарии:
1. Проверьте консоль в IE11 dev tools, чтобы найти ошибку, которую вы можете отладить
2. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference /… — ie 11 не поддерживает
**
3. @RoryMcCrossan
^
— это xor .4. просто напишите это правильно с первого раза.
5. Вы не найдете простого регулярного выражения — я уверен, что кто-нибудь сможет что-нибудь придумать, но, серьезно, если вы ДОЛЖНЫ поддерживать IE, то забудьте ES6 полностью — IE11 поддерживает только 11% ES6 — серьезно, он поддерживает только 99% ES5! и 1% ES2016 — придерживайтесь ES5, если вы должны поддерживать IE11 — или вырезать IE11, чтобы Internet Explorer был ближе к смерти от тысячи сокращений
Ответ №1:
Попытка сделать это с помощью регулярного выражения будет непростой. Вместо этого используйте транспилятор или, по крайней мере, анализатор ECMAScript.
Вот пример, как это можно сделать с помощью синтаксического анализатора esprima. Этот API создает дерево AST. Приведенный ниже код ищет **
оператор в этом дереве и собирает смещения, в которых должна измениться входная строка. Затем эти смещения сортируются в порядке убывания, чтобы применить их в правильном порядке к входной строке.
Обратите внимание, что этот код не пытается сохранить какие-либо круглые скобки. Данные во входных данных сохраняются, и для каждого из вызовов добавляется дополнительная пара Math.pow
.
function convert(input) {
let modifs = [];
function recur(ast) {
if (Object(ast) !== ast) return; // not an object
if (ast.type === "BinaryExpression" amp;amp; 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/esprima@4.0.1/dist/esprima.min.js"></script>