[英]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.