Java 如何模式匹配左括号和后面的特定字符

Java 如何模式匹配左括号和后面的特定字符,java,regex,pattern-matching,Java,Regex,Pattern Matching,简单地说,我试图找到一个模式,如果有一个方程有a(并检查之后是否有a+,或-或*或/,一个例子是 4+3*(+2/1+3)*1试试这个解析器 number := [0-9]+ expression := '(', expression, ')', op | number, op op := '+', expression | '-', expression | '/', expression | '*', expression | epsilon 在伪EBNF中 public class E

简单地说,我试图找到一个模式,如果有一个方程有a(并检查之后是否有a+,或-或*或/,一个例子是


4+3*(+2/1+3)*1试试这个解析器

number := [0-9]+ 
expression := '(', expression, ')', op | number, op
op := '+', expression | '-', expression | '/', expression | '*', expression | epsilon
在伪EBNF中

public class ExpressionParser {
    private enum Type {
        LB, RB, NUMBER, OP, END
    }

    private static class Token {
        Type type;
        String value;
        int current;

        public Token(Type type, String value, int current) {
            super();
            this.type = type;
            this.value = value;
            this.current = current;
        }

        @Override
        public String toString() {
            return "Token [type=" + type + ", value=" + value + ", current="
                    + current + "]";
        }

    }

    private static class Lexer {

        private int current;
        private String input;

        public Lexer(String input) {
            this.input = input;
        }

        private char getChar() {
            return input.charAt(current++);
        }

        private void unputChar() {
            current--;
        }

        private boolean hasNextChar() {
            return current < input.length();
        }

        Token next() {

            if (!hasNextChar()) {
                return new Token(Type.END, "", current);
            }

            char c = getChar();

            while (Character.isWhitespace(c)) {
                c = getChar();
            }

            if (c == '(') {
                return new Token(Type.LB, "(", current);
            }

            if (c == ')') {
                return new Token(Type.RB, ")", current);
            }

            if (c == '+' || c == '-' || c == '*' || c == '/') {
                return new Token(Type.OP, "" + c, current);
            }

            StringBuilder buffer = new StringBuilder();
            while (hasNextChar()) {

                c = getChar();

                if (Character.isDigit(c)) {
                    buffer.append(c);
                } else {
                    unputChar();
                    break;
                }

            }

            return new Token(Type.NUMBER, buffer.toString(), current);

        }
    }

    private static boolean match(Type type) {
        return type == currentToken.type;
    }

    private static void consume(Type type) {
        if (!match(type)) {
            throw new RuntimeException(String.format("Should be %s is %s",
                    type.name(), currentToken.toString()));
        }
        currentToken = lexer.next();
    }

    private static void operation() {

        if (match(Type.OP)) {
            consume(Type.OP);
            expression();
        }

    }

    private static void expression() {

        while (!match(Type.END)) {

            if (match(Type.NUMBER)) {
                consume(Type.NUMBER);
                operation();
            } else if (match(Type.LB)) {
                consume(Type.LB);
                expression();
                consume(Type.RB);
                operation();
            } else {
                break;
            }

        }

    }

    private static Lexer lexer;
    private static Token currentToken;

    private static void parse(String line) {

        lexer = new Lexer(line);
        currentToken = lexer.next();

        try {
            expression();
            consume(Type.END);
            System.out
                    .println(String.format("%s is a proper expression", line));
        } catch (Exception e) {
            System.out.println(String.format(
                    "%s is not a proper expression because %s", line,
                    e.getMessage()));
        }

    }

    public static void main(String[] args) {

        parse("4 + 3 * (+2/1 + 3) * 1");
        parse("4 + 3 * (2/1+3) * 1");
        parse("((((5/9)+6)-4)/1)");
        parse("54-2*(23-2)/2");
        parse("54-2*(-23-2)/2");

    }
}

您的文本可以包含嵌套的括号吗?我尝试了模式y=Pattern.compile([(].*);模式z=Pattern.compile([(][+-/*].*));模式a=Pattern.compile(\([+-/*]);模式b=Pattern.compile((/().*))以及更多的变体combinations@Pshemo是的,我想是的。只要想想任何表达(((5/9)+6)-4)/1) 或者54-2*(23-2)/2,但在任何时候,它们都不能是左括号后面的任何符号,因此54-2*(-23-2)/2是错误的。我想说正则表达式不是适合这项工作的工具。你应该编写一个适当的递归解析器。你能解释更多吗?我仍在尝试学习这方面的知识:)
4 + 3 * (+2/1 + 3) * 1 is not a proper expression because Should be RB is Token [type=OP, value=+, current=10]
4 + 3 * (2/1+3) * 1 is a proper expression
((((5/9)+6)-4)/1) is a proper expression
54-2*(23-2)/2 is a proper expression
54-2*(-23-2)/2 is not a proper expression because Should be RB is Token [type=OP, value=-, current=7]