我试图确定给定的输入是否是有效的数学表达式。这是我提出的当前代码,但如果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)
另外,如果可能,还可以包含有关正则表达式如何工作的简单说明吗?我对这个话题很陌生。我从概念上理解它,但在我的代码中实现它时遇到了麻烦。
答案 0 :(得分:0)
正如几条评论所说,只是一个正则表达式匹配,你所要求的是不可能的。事实上,匹配平衡括号是一个经典的问题之一,这是一个简单的正则表达式无法解决的问题。只要您的数学表达式可以包含任意嵌套的括号,就不能使用正则表达式对其进行验证。
但是, 可以验证更小的语言,然后我们可以通过一些编码将其构建到您的语言的验证例程中。较小的语言就像您的语言,但只有一个变化:不允许使用括号。然后,语言中的有效表达式如下所示:
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对包围) ,验证parens中的东西是否与简单语言匹配,然后用一些整数替换该块(包括周围的parens),用空格包围,以便它被认为与周围的东西分开。所以逻辑是这样的:
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
- 没有更多的parens,所以问:
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*");