问题:表达式语法是否正确?
规则:从左到右的数字左右括号应该是相同的,并且按照良好惯例打开 - 关闭,第一个左边,例如:
(xxx(xx)()) - OK
((())) - OK
(x(x(x(x(x))X)x)x) - OK
(()() - WRONG
)() - WRONG
我的解决方案:
private boolean syntaxValidator(String str) {
if (StringUtils.isBlank(str)) {
return false;
} else {
int counter = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == '(') {
counter++;
} else if (str.charAt(i) == ')') {
counter--;
if (counter < 0) {
return false;
}
}
}
if (counter == 0) {
return true;
} else {
return false;
}
}
}
有效吗?可以通过使用正则表达式来解决吗?怎么样?
答案 0 :(得分:4)
有效吗?
是的,在我看来,只要你将建议纳入另一个答案。通常,如何通过使用堆栈来验证多种类型的括号。如果字符是一个开括号类型的字符((
,[
,{
之一),请按字符顶部的字符。遇到一种结束类型的字符()
,}
,]
)时,弹出堆栈并比较当前字符和弹出字符。如果不相等,则表示语法错误。
可以使用正则表达式解决吗?
这不是正则表达式的工作。支架验证通常需要您进行某种计数(就像您现在所做的那样)。正则表达式本质上不保留任何计数。虽然,我认为,通过使用PCRE可以实现这一点,但我现在还不记得了。
答案 1 :(得分:3)
正则表达式不会削减它,你的解决方案似乎没问题。为了提高效率,请执行此操作(这不是整个代码,只是一个代码段):
int strLength = str.length(); // so you don't have to call this method every time
for (int i = 0; i < strLength; i++) {
char ch = str.charAt(i); // so you won't have to call this twice
if (ch == '(') {
counter++;
} else if (ch == ')') {
counter--;
if (counter < 0) {
return false;
}
}
}
上述评论中的建议return counter == 0;
也很棒。
答案 2 :(得分:2)
您无法使用正则表达式解决此问题。您至少需要无上下文解析器来完成它。
在上下文无关语法中你可以写
N = '(' M ')'
在正则表达式中,这是不允许的。与无上下文语法相比,此限制允许更快的匹配。