如何在switch语句中匹配正则表达式?

hax*_*ode 5 java regex switch-statement

我正在尝试将令牌与函数中的switch语句进行匹配,其中一个令牌需要能够识别下面代码中正则表达式定义的任何字符串或任何数字.

基本上,是否可以针对像这样的情况定义正则表达式 case "[a-z]+":

显然我现在拥有它的方式,除非我通过STRINGNUMBER作为参数,否则我的模式是不可达的.

public Token analyzeToken(String token) {
      Token tokenType = null;     

      switch (token) {

         case "STRING":
            Pattern p = Pattern.compile("[a-z]+");
            Matcher m = p.matcher(token);
            if(m.matches()) {
               tokenType = Token.STRING;
               break;
            }
         case "NUMBER":
            Pattern p = Pattern.compile("[0-9]+");
            Matcher m = p.matcher(token);
            if(m.matches()) {
               tokenType = Token.NUMBER;
               break;

         case "(":
            tokenType = Token.LEFT_PAREN;
            break;
         case ")":
            tokenType = Token.RIGHT_PAREN;
            break;
         case ".":
            tokenType = Token.PERIOD;
            break;
         case ":":
            tokenType = Token.COLON;
            break;
         case ";":
            tokenType = Token.SEMICOLON;

         default:
            tokenType = TOKEN.UNKNOWN;
            break;

      }
   }
Run Code Online (Sandbox Code Playgroud)

das*_*ght 6

不要在switch声明中这样做,在条件中或在更好的循环中执行:

private interface TokenMatcher {
    Token match(String s);
}
static List<TokenMatcher> matchers = new ArrayList<>();
static {
    final Pattern strPattern = Pattern.compile("[a-z]+");
    final Pattern numPattern = Pattern.compile("[0-9]+");
    matchers.add( new TokenMatcher {
        public Token match(String s) {
            Matcher m = strPattern.matcher(s);
            return m.matches() ? Token.STRING : null;
        }
    });
    matchers.add( new TokenMatcher {
        public Token match(String s) {
            Matcher m = numPattern.matcher(s);
            return m.matches() ? Token.NUMBER : null;
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

现在你可以这样做:

static Token match(String s) {
    for (TokenMatcher m : matchers) {
        Token t = m.match(s);
        if (t != null) {
            return t;
        }
    }
    return TOKEN.UNKNOWN;
}
Run Code Online (Sandbox Code Playgroud)

for循环已经发生的switch声明,而在条目matchers列表已经发生的个人case在S switch.添加新的令牌类型就像向matchers列表中添加新模式及其相关实现一样简单.

编辑:您可以通过将上面的接口替换为类来缩短解决方案,如下所示:

private static final class TokenMatcher {
    private final Pattern p;
    private final Token t;
    public TokenMatcher(String pString, Token t) {
        p = Pattern.compile(pString);
        this.t = t;
    }
    public Token match(String s) {
        Matcher m = p.matcher(s);
        return m.matches() ? t: null;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你的matchers初始化可以像这样完成:

matchers.add(new TokenMatcher("[a-z]+", Token.STRING));
matchers.add(new TokenMatcher("[0-9]+", Token.NUMBER));
Run Code Online (Sandbox Code Playgroud)