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