簡體   English   中英

用於驗證數學表達式的正則表達式

[英]Regular Expression to Validate a Math Expression

我正在嘗試確定給定的輸入是否為有效的數學表達式。 這是我目前想出的代碼,但是只有Input為單個整數(例如100、200、5、7)時,它才返回true。

Pattern pattern = Pattern.compile("-?\\w+|[-+*%/()]");
Matcher match = pattern.matcher(Input);

if(pattern.matcher(Input).matches())
{
    System.out.print("True");
}
else
    System.out.print("False");

有關我要完成的工作的更多信息:

為簡單起見, 假設整數 (因此,不包含變量和小數位)。
運算符為:+,-,*,/,%。
僅帶括號(因此沒有括號或花括號)。

例子:

有效:

123  
1*2(3+4)%7  
3--4+5*-7  
13(12)+11-(7*15%(11-2)/4)  
(((((-99999)))))

無效

1+2)  
)5--  
3+*12  
)(++**//
(50)+12)

另外,如果可能的話,是否還可以包含有關Regex工作原理的簡單解釋? 我對這個話題很陌生。 我從概念上理解它,但是在我的代碼中難以實現。

如幾條評論所述, 使用正則表達式匹配是您無法要求的。 實際上,匹配的平衡括號是經典的“簡單的正則表達式無法解決的問題”之一。 只要您的數學表達式可以包含任意嵌套的括號,就不能使用正則表達式對其進行驗證。

然而,就可以驗證一個較小的語言,然后我們可以構建成與編碼的一點點您的語言的驗證程序。 較小的語言與您的語言一樣,但有一個變化: 不允許使用括號 然后,該語言中的有效表達式如下所示:

INTEGER OP INTEGER OP INTEGER OP .... OP INTEGER

另一種說法是“一個INTEGER后跟零個或多個OP INTEGER序列”。 可以將其轉換為正則表達式,例如:

Pattern simpleLang = Pattern.compile("-?\\d+([-+*%/]-?\\d+)*");

所以-?\\d+表示INTEGER[-+*%/]表示OP 好的,現在我們該如何使用呢? 好吧,首先讓我們對其進行修改,以在整數之間添加任意空格,並使模式成為static ,因為我們將把此驗證邏輯包裝在一個類中:

static Pattern simpleLang = Pattern.compile("\\s*-?\\d+(\\s*[-+*%/]\\s*-?\\d+)*\\s*");

(但請注意,我們不允許一個負號和它后面的號碼之間的空格,所以3 - - 4是不允許的,即使3 - -4是允許的)

現在,要驗證完整語言,我們需要做的是重復查找位於最內括號級別的塊(因此,一個塊本身不包含任何括號,但被一個開閉括號對包圍),請驗證parens與簡單語言匹配,然后用一些整數(用空格包圍)替換該塊(包括周圍的paren),以便將其與周圍的東西分開。 所以邏輯是這樣的:

  • expr進來是11 - (7 * 15 % (11 - 2) / 4)
  • 最里面的括號塊是11 - 2
  • 請問11 - 2比賽的簡單的語言? 是!
  • 用一些整數替換(11 - 2) 例如,使用1
  • expr現在是11 - (7 * 15 % 1 / 4)
  • 最里面帶括號的塊是7 * 15 % 1 / 4
  • 7 * 15 % 1 / 4與簡單語言匹配? 是!
  • 用一些整數替換(7 * 15 % 1 / 4) 例如,使用1
  • expr現在是11 - 1
  • 不用了,請問: expr與簡單語言匹配? 是!

在代碼中,它可以做到:

static Pattern simpleLang = Pattern.compile("\\s*-?\\d+(\\s*[-+*%/]\\s*-?\\d+)*\\s*");
static Pattern innerParen = Pattern.compile("[(]([^()]*)[)]");
public static boolean validateExpr(String expr) {
    while (expr.contains(")") || expr.contains("(")) {
        Matcher m = innerParen.matcher(expr);
        if (m.find()) {
            if (!simpleLang.matcher(m.group(1)).matches()) {
                return false;
            }
            expr = expr.substring(0,m.start()) + " 1 " + expr.substring(m.end());
        } else {
            // we have parens but not an innermost paren-free region
            // This implies mismatched parens
            return false;
        }
    }
    return simpleLang.matcher(expr).matches();
}

請注意,有一個您稱為“有效”的表達式,它不會稱為有效:即表達式13(12)+11-(7*15%(11-2)/4) 這將被視為無效,因為在13和12之間沒有運算符。如果您希望允許這種隱式乘法,最簡單的方法是添加 (空格字符)作為簡單語言中允許的運算符,因此請將simpleLang更改為:

static Pattern simpleLang = Pattern.compile("\\s*-?\\d+(\\s*[-+ *%/]\\s*-?\\d+)*\\s*");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM