【发布时间】:2011-04-27 13:12:18
【问题描述】:
我正在考虑使用 Java 中的正则表达式验证一个中缀表示法,它由作为操作数的字母和作为运算符的 +-*/$ [例如:A+B-(C/D)$(E+F)] 组成。有没有更好的办法?有没有我可以使用的正则表达式模式?
【问题讨论】:
-
正则表达式是验证 CFG 的错误工具 - 上下文无关语法。
标签: java regex infix-notation
我正在考虑使用 Java 中的正则表达式验证一个中缀表示法,它由作为操作数的字母和作为运算符的 +-*/$ [例如:A+B-(C/D)$(E+F)] 组成。有没有更好的办法?有没有我可以使用的正则表达式模式?
【问题讨论】:
标签: java regex infix-notation
我不熟悉infix 的语言语法,但您当然可以进行第一次验证检查,简单地验证字符串中的所有字符是否有效(即可接受的字符 = A-Z、@987654323 @、-、*、/、$、( 和 ))。这是一个检查有效字符的 Java 程序,还包括一个检查不平衡(可能嵌套)括号的函数:
import java.util.regex.*;
public class TEST {
public static void main(String[] args) {
String s = "A+B-(C/D)$(E+F)";
Pattern regex = Pattern.compile(
"# Verify that a string contains only specified characters.\n" +
"^ # Anchor to start of string\n" +
"[A-Z+\\-*/$()]+ # Match one or more valid characters\n" +
"$ # Anchor to end of string\n",
Pattern.COMMENTS);
Matcher m = regex.matcher(s);
if (m.find()) {
System.out.print("OK: String has only valid characters.\n");
} else {
System.out.print("ERROR: String has invalid characters.\n");
}
// Verify the string contains only balanced parentheses.
if (checkParens(s)) {
System.out.print("OK: String has no unbalanced parentheses.\n");
} else {
System.out.print("ERROR: String has unbalanced parentheses.\n");
}
}
// Function checks is string contains any unbalanced parentheses.
public static Boolean checkParens(String s) {
Pattern regex = Pattern.compile("\\(([^()]*)\\)");
Matcher m = regex.matcher(s);
// Loop removes matching nested parentheses from inside out.
while (m.find()) {
s = m.replaceFirst(m.group(1));
m.reset(s);
}
regex = Pattern.compile("[()]");
m = regex.matcher(s);
// Check if there are any erroneous parentheses left over.
if (m.find()) {
return false; // String has unbalanced parens.
}
return true; // String has balanced parens.
}
}
这不会验证语法,但作为第一次测试过滤明显错误的字符串可能很有用。
【讨论】:
可能有点矫枉过正,但您可以考虑使用成熟的解析器生成器,例如 ANTLR (http://www.antlr.org/)。使用 ANTLR,您可以创建自动为您生成 java 代码的规则。假设您在输入中只有有效字符,这是一个语法分析问题,否则您需要先通过词法分析来验证字符流。
对于语法分析,您可能有如下规则:
PLUS : '+' ;
etc...
expression:
term ( ( PLUS | MINUS | MULTIPLY | DIVIDE )^ term )*
;
term:
constant
| OPENPAREN! expression CLOSEPAREN!
;
常量是整数/实数。如果 ANTLR 生成的解析器代码无法将输入与您的解析器规则匹配,它将抛出异常,以便您确定代码是否有效。
【讨论】:
您可能可以使用递归 PCRE..但这可能是一个 PITA。
由于您只想验证它,因此可以非常简单地完成。只需使用堆栈,将所有元素一个一个推入并删除有效表达式。
定义一些规则,例如:
然后:
每次删除一个表达式后,添加一个虚拟字母表。重复前面的步骤。 如果结果是字母表,则表达式有效。
或类似的东西..
【讨论】: