我有一个函数,可以接受字符串,将其解释为计算结果并返回计算结果,有效计算示例包括:
3(log(e+pi^(22/3)))
44+3*(pi+2)/root(7)
该函数非常繁琐,因此我只想在String实际上是一个计算时才运行它。在添加诸如log和root,pi和e以及隐式乘法之类的功能之前,我使用了以下正则表达式:
/^((-?([0-9]+?\.)?[0-9]+?)\s?([+\-*\/%^]|(\*\*))\s?)+?(-?([0-9]+?\.)?[0-9]+?)$/
不再起作用。在这一点上,我什至不确定正则表达式是否有意义。我希望大约有0.1%的字符串可以匹配(这是有效的计算方法)。
您对如何建立表现良好的常规有任何想法吗? 表达式(该函数本身确定天气是否有效 计算本身,但是需要很长时间,因此没有100%的准确性 所需)还是验证计算的功能?
答案 0 :(得分:1)
您要提出的问题本质上是Regular Expression AND String Parsing。 恕我直言,您的字符串计算可以构建为语法树。为它构建一个解析器比创建一个相当复杂的正则表达式要容易得多。
答案 1 :(得分:0)
我写了一个验证计算的函数,这是代码:
const isValidCalc = (calc) => {
contains = {
br: false,
num: false,
let: false,
op: false,
}
let prev;
let level = 0;
return ![...calc.replace(/\*\*/g, "^").replace(/ /g, "").replace(/e/g, Math.E).replace(/pi/g, Math.PI)].some(el => {
if (el === "(") {
prev = "open";
level++;
return false;
};
if (el === ")") {
if (level-- === 0 || prev === "letter") return true;
prev = "close";
contains.br = true;
return false;
}
if (_.is.Operation(el)) {
if (prev === "operator" || prev === "letter") return true;
prev = "operator";
contains.op = true;
return false;
}
if (_.is.Numeric(el) || el === ".") {
if (prev === "close" || prev === "letter") return true;
prev = "numeric"
contains.num = true;
return false;
}
if (_.is.Letter(el)) {
prev = "letter"
contains.let = true;
return false;
}
return true;
}) && level === 0 && contains.num && (!contains.let || contains.br) && (contains.let || contains.op);
};