使用Regex在Java中使用字符串

时间:2014-04-07 23:03:56

标签: java regex lexer

由于某种原因,while循环只进行一次,然后选择NUMBER然后退出。有没有人知道为什么它不会激活String的其余部分?我所拥有的只是1 + 2的输入。非常感谢任何帮助!!

public Lexer(String input) throws TokenMismatchException {
        tokens = new ArrayList<Token>();

        // Lexing logic begins here
        StringBuffer tokenPatternsBuffer = new StringBuffer();
        for (Type type : Type.values())
            tokenPatternsBuffer.append(String.format("|(?<%s>%s)", type.name(), type.pattern));
        Pattern tokenPatterns = Pattern.compile(new String(tokenPatternsBuffer.substring(1)));

        // Begin matching tokens
        Matcher matcher = tokenPatterns.matcher(input.replaceAll(" ", ""));
        while (matcher.find()) {
            if (matcher.group(Type.NUMBER.name()) != null) {
                tokens.add(new Token(Type.NUMBER, matcher.group(Type.NUMBER.name())));
                continue;
            } else if (matcher.group(Type.OPERATOR.name()) != null) {
                tokens.add(new Token(Type.OPERATOR, matcher.group(Type.OPERATOR.name())));
                continue;
            } else if (matcher.group(Type.UNIT.name()) != null) {
                tokens.add(new Token(Type.UNIT, matcher.group(Type.UNIT.name())));
                continue;
            } else if (matcher.group(Type.PARENTHESES.name()) != null) {
                tokens.add(new Token(Type.PARENTHESES, matcher.group(Type.PARENTHESES.name())));
                continue;
            } else {
                throw new TokenMismatchException();
            }
        }
    }

enum Type {
    NUMBER("[0-9]+.*[0-9]*"), OPERATOR("[*|/|+|-]"), UNIT("[in|pt]"), PARENTHESES("[(|)]");

    public final String pattern;

    private Type(String pattern) {
        this.pattern = pattern;
    }
}

1 个答案:

答案 0 :(得分:1)

这种模式:

"[0-9]+.*[0-9]*"

匹配一个或多个数字,后跟零个或多个任何字符,后跟零个或多个数字。点是正则表达式中的特殊字符,表示“任何字符”。如果你想要匹配一个小数点,你需要在点之前加一个反斜杠:

"[0-9]+\\.*[0-9]*"

(反斜杠加倍,因为它在Java字符串文字中。)如果进行了一次修复,它似乎可以在"1 + 2"上工作。但是,您的其他一些模式显示对[]在正则表达式中的作用存在一些误解。这是一个“字符类”,它匹配您在括号中列出的任何字符,但-可用于一系列字符(如0-9)。所以

"[*|/|+|-]"

匹配任何字符*|/+-|并不代表“或”在方括号内)。 -在这里不被视为范围运算符,因为它是最后一个,但最好还是养成在它前面使用\的习惯,所以你想要

"[*/+\\-]"

类似地,

"[in|pt]"

匹配五个字符in|pt中的一个 - 当然不是您想要的。你可能想要

"(in|pt)"

匹配"in""pt";在您的情况下,括号可能不是必需的,但在不同的情况下,当模式包含在较大的字符串中时,可能有必要阻止某些其他字符包含在其中一个替代字符中。