【问题标题】:Lexing a String in Java with Regex使用正则表达式在 Java 中对字符串进行词法分析
【发布时间】:2014-04-07 23:03:56
【问题描述】:

由于某种原因,while 循环只经过一次,拿起NUMBER 然后退出。有谁知道为什么它没有对字符串的其余部分进行词法分析?我所拥有的只是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;
    }
}

【问题讨论】:

    标签: java regex lexer


    【解决方案1】:

    这种模式:

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

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

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

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

    "[*|/|+|-]"
    

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

    "[*/+\\-]"
    

    同样,

    "[in|pt]"
    

    匹配in|pt 这五个字符之一——当然不是你想要的。你可能想要

    "(in|pt)"
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-28
      • 1970-01-01
      • 2010-11-22
      • 1970-01-01
      • 1970-01-01
      • 2015-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多