获取在 Java Regex 中返回匹配项的组

问题描述 投票:0回答:1

我正在用 Java 编写一个简单的词法分析器,该类的主要方法如下所示:

public LinkedList<Token> tokenize() {
        // Create a matcher for the input string
        Matcher matcher = tokensPattern.matcher(input);

        // Create an empty list for the result
        LinkedList<Token> tokensList = new LinkedList<>();

        // While matches are found, keep looping        
        while (matcher.find()) {
            // Get match
            String matchStr = matcher.group();
            
            // Check which token matched to create the apropriate Token object
            for(PossibleTokens t : PossibleTokens.values()) {
                if (matcher.group(t.name()) != null)
                    tokensList.add(new Token(t.name(), matchStr));
            }
        }
        
        // Return list of Tokens
        return tokensList;
    }

我将词法分析器的可能标记保留在名为

PossibleTokens
的枚举中。该枚举中的每个元素都包含它所代表的标记的正则表达式模式。此外,常量的名称用于为每个令牌创建相应的命名捕获组。

代码按预期工作,但我不太喜欢的是,为了验证哪个组已匹配,我需要循环遍历所有组并验证哪个组不为空。

有没有更好的方法来获取匹配的组而不需要循环遍历所有组?

这将非常有用,因为我计划将来扩展此 Lexer 接受的令牌。所以每次都检查每个组是非常低效的。

java regex regex-group lexer
1个回答
0
投票

您可以通过使用映射来存储匹配器中的命名捕获组来简化检查哪个令牌组匹配的逻辑,然后直接根据组名称检查匹配。这样,您就可以避免每次都循环遍历所有可能的标记。

您可以在

tokenize
方法中采取以下方法来提高效率:

public LinkedList<Token> tokenize() {
    // Create a matcher for the input string
    Matcher matcher = tokensPattern.matcher(input);

    // Create an empty list for the result
    LinkedList<Token> tokensList = new LinkedList<>();

    // While matches are found, keep looping
    while (matcher.find()) {
        // Create a map to store the named-capturing groups
        Map<String, String> namedGroups = new HashMap<>();
        
        // Get all named groups from the matcher
        for (String group : tokensPattern.namedGroups()) {
            namedGroups.put(group, matcher.group(group));
        }

        // Check which token matched to create the appropriate Token object
        for(PossibleTokens t : PossibleTokens.values()) {
            String tokenValue = namedGroups.get(t.name());
            if (tokenValue != null) {
                tokensList.add(new Token(t.name(), tokenValue));
                break; // Exit the loop once a match is found
            }
        }
    }

    // Return list of Tokens
    return tokensList;
}

通过使用 Map 来存储命名捕获组并直接根据组名称检查是否匹配,可以提高确定哪个 token 匹配的效率,而无需每次都循环遍历所有可能的 token。

© www.soinside.com 2019 - 2024. All rights reserved.