验证JavaScript中的数学表达式?
我正在开发一个JavaScript应用程序,该应用程序需要验证数学表达式,但我不知道如何做到这一点 我的语法示例是验证JavaScript中的数学表达式?,javascript,jquery,regex,algorithm,parsing,Javascript,Jquery,Regex,Algorithm,Parsing,我正在开发一个JavaScript应用程序,该应用程序需要验证数学表达式,但我不知道如何做到这一点 我的语法示例是 (keyword1 + keyword2) * (keyword1 / (keyword1 + keyword1)) 这里,keyword1和keyword2可以是任何数字,有效的运算符是标准的加法、减法、乘法和除法 有人知道如何使用正则表达式吗?有很多方法。我建议你仔细阅读上下文无关的语法/语言。这有点简单(虽然它确实是一个CFG),但了解语法和解析技术总是有帮助的 我应该注意
(keyword1 + keyword2) * (keyword1 / (keyword1 + keyword1))
这里,keyword1
和keyword2
可以是任何数字,有效的运算符是标准的加法、减法、乘法和除法
有人知道如何使用正则表达式吗?有很多方法。我建议你仔细阅读上下文无关的语法/语言。这有点简单(虽然它确实是一个CFG),但了解语法和解析技术总是有帮助的 我应该注意到,您在这里描述的语言不是正则的,因此没有正则表达式能够解析它(简单地使用泵引理就可以证明这一点)。此外,我建议不要使用它们来提供有意义的帮助——它们不是强大的解析工具 您可以使用解析库来解决更复杂的语法并实现简单的case。如果您正在寻找更直接的解决方案,递归是您的朋友: 让我们将有效表达式定义为:
expression ::= literal | expression op expression | (expression)
op ::= + | - | / | *
其中,literal是一个数字
想一想调整定义如何改变语言,特别是想一想不同的实现如何用不同的策略解决这个问题:从左到右的求值,或者相反,等等。简单的解决方法是,我们可以向服务器发送ajax请求,如果返回正确的值而没有错误,则可能是带有表达式的数据库。我的表达式有效,否则无效
简单ha~正如@davin所指出的,这不是可以用正则表达式解析的东西。但是,您可以使用上下文无关语法来解析它。认识到这里需要CFG是一个很大的步骤,但是从CFG到解析算法可能有点棘手 要解析这个表达式,我建议使用两步方法,就像在编译器中找到的方法一样。首先,您需要将字符串标记为一组逻辑单元。也就是说,您将转换字符串
(1 + 6) * 7
列入名单
["(", "1", "+", "6", ")", "*", "7"]
有很多方法可以完成这一步。您可以编写一个手动标记器,或者使用一组正则表达式来分割字符串。此时,您可以检测词法错误,报告字符串中是否有任何不应该存在的内容。例如,字符“,”与这些表达式中的任何一个都没有关系,您可以在这里检测到这一点
一旦您对字符串进行了标记化,您将希望解析标记流,以验证它是否有效,并且(可选)为数学表达式建立适当的内部表示。其中一个更著名(也是最简单)的算法是,你可以在一小时内轻松编写出来。如果您对解析这些表达式的重量级类感兴趣,您应该考虑查看解析器生成器,这些分析器生成器能够处理更复杂的表达式。如果您想在客户端进行解析,会出现一个快速搜索。如果您想处理服务器上的解析,请考虑查看BISY或ANTLR工具,它们是非常强大的解析器生成器。
希望这有帮助 我必须用Angular设计动态公式生成器,在将给定表达式传递给DB之前,我必须检查其是否有效 我写这段代码是为了验证数学表达式,它可以帮助您 /*代码从这里开始*/ 验证(表达式){
let previous=0;
设前1=0;
设运算符perand=1;
for(设i=0;iprevious1){
上一个1=操作员和操作员;
运算符perand++;
先前=0;
}else if(上一个!=0&&previous1!=0&&previous1){
上一个1=操作员和操作员;
运算符perand++;
先前=0;
}否则如果(previous!=0&&previous1!=0&&previous您的语法示例的括号不匹配。感谢您的回复,我如何在上面编写正则表达式this@Roshan,单是正则表达式的功能还不足以解析它。编写一个简单的递归实现(按照语法定义)将更容易、更易于管理。@Davin,如果你的词法单位足够简单(在数字的情况下,我会说“很可能”),那么使用regexps到lex是完全合理的。但是,这取决于域,所以这不是一般规则。一个合适的解析器才是真正的方法。+1表示“上下文无关语法”,自从我学习“编程语言”之后,我就没有考虑过这些在大学里=)
let previous = 0;
let previous1 = 0;
let operatorOperand = 1;
for (let i = 0; i < expression.length; i++) {
let c = expression[i];
if (c == ")") {
} else if (c == "(") {
let j = this.indexOfFromGivenIndexInArray(expression, ")", i);
if (j == -1) return false;
let substring = expression.slice(i + 1, j - i);
while (this.getcharactercount(substring, "(") != this.getcharactercount(substring, ")")) {
if (j < expression.length - 1) j = this.indexOfFromGivenIndexInArray(expression, ")", j + 1);
else break;
substring = expression.slice(i + 1, j - i);
}
console.log(substring, "PHASE 2");
i = j - 1;
if (this.validate(substring) == true) {
if (previous != 0 && previous1 != 0 && previous > previous1) {
previous1 = operatorOperand;
operatorOperand++;
previous = 0;
} else if (previous != 0 && previous1 != 0 && previous <= previous1) {
return false;
} else if (previous1 != 0) {
return false;
} else {
previous1 = operatorOperand;
operatorOperand++;
}
} else {
return false;
}
} else if (c == "+" || c == "-" || c == "AND" || c == "OR") {
if (previous != 0) {
return false;
}
previous = operatorOperand;
operatorOperand++;
} else {
if (previous != 0 && previous1 != 0 && previous > previous1) {
previous1 = operatorOperand;
operatorOperand++;
previous = 0;
} else if (previous != 0 && previous1 != 0 && previous <= previous1) {
return false;
} else if (previous1 != 0) {
return false;
} else {
previous1 = operatorOperand;
operatorOperand++;
}
}
}
if (previous != 0) return false;
return true;
}
indexOfFromGivenIndexInArray(expression, ch, index: number): number {
console.log("eeee", expression, ch, index);
for (let ind = index; ind < expression.length; ind++) {
console.log(ch, "DIFF", expression[ind], "DIFF", ind);
if (expression[ind] == ch) {
return ind;
}
}
return -1;
}
getcharactercount(exp, _c): number {
let count = 0;
for (let ch in exp) {
if (ch == _c) {
count++;
}
}
return count;
}