【问题标题】:Validating an infix notation possibly using regex可能使用正则表达式验证中缀符号
【发布时间】:2011-04-27 13:12:18
【问题描述】:

我正在考虑使用 Java 中的正则表达式验证一个中缀表示法,它由作为操作数的字母和作为运算符的 +-*/$ [例如:A+B-(C/D)$(E+F)] 组成。有没有更好的办法?有没有我可以使用的正则表达式模式?

【问题讨论】:

标签: java regex infix-notation


【解决方案1】:

我不熟悉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.
    }
}

这不会验证语法,但作为第一次测试过滤明显错误的字符串可能很有用。

【讨论】:

  • 首先这是令人难以置信的低效。其次,如果你这样使用它,为什么不将 [A-Z][+\\-*/$][A-Z] 替换为 A 和 \([A-Z]\) 替换为 A。所以你最终得到一个空如果表达式有效则为字符串
【解决方案2】:

可能有点矫枉过正,但您可以考虑使用成熟的解析器生成器,例如 ANTLR (http://www.antlr.org/)。使用 ANTLR,您可以创建自动为您生成 java 代码的规则。假设您在输入中只有有效字符,这是一个语法分析问题,否则您需要先通过词法分析来验证字符流。

对于语法分析,您可能有如下规则:

PLUS : '+' ;
etc...

expression:
         term ( ( PLUS | MINUS | MULTIPLY | DIVIDE )^ term )*
      ;
term:
    constant
  | OPENPAREN! expression CLOSEPAREN!
  ;

常量是整数/实数。如果 ANTLR 生成的解析器代码无法将输入与您的解析器规则匹配,它将抛出异常,以便您确定代码是否有效。

【讨论】:

    【解决方案3】:

    您可能可以使用递归 PCRE..但这可能是一个 PITA。

    由于您只想验证它,因此可以非常简单地完成。只需使用堆栈,将所有元素一个一个推入并删除有效表达式。

    定义一些规则,例如:

    • 只有在栈顶有字母时才允许使用运算符
    • 只有在堆栈顶部有运算符时才允许使用字母或括号
    • 如果堆栈为空,则一切都允许

    然后:

    • 如果遇到右括号,请删除左括号之前的所有内容。
    • 如果遇到字母,请删除该表达式

    每次删除一个表达式后,添加一个虚拟字母表。重复前面的步骤。 如果结果是字母表,则表达式有效。

    或类似的东西..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-15
      • 2019-02-26
      • 2016-12-09
      • 1970-01-01
      • 1970-01-01
      • 2012-10-09
      相关资源
      最近更新 更多