验证JavaScript中的数学表达式?

验证JavaScript中的数学表达式?,javascript,jquery,regex,algorithm,parsing,Javascript,Jquery,Regex,Algorithm,Parsing,我正在开发一个JavaScript应用程序,该应用程序需要验证数学表达式,但我不知道如何做到这一点 我的语法示例是 (keyword1 + keyword2) * (keyword1 / (keyword1 + keyword1)) 这里,keyword1和keyword2可以是任何数字,有效的运算符是标准的加法、减法、乘法和除法 有人知道如何使用正则表达式吗?有很多方法。我建议你仔细阅读上下文无关的语法/语言。这有点简单(虽然它确实是一个CFG),但了解语法和解析技术总是有帮助的 我应该注意

我正在开发一个JavaScript应用程序,该应用程序需要验证数学表达式,但我不知道如何做到这一点

我的语法示例是

(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;
}