public StringFormatGroup.FormatResult match(String uri) {
        final List<String> slices = splitByCharacter(uri);
        if (slices.size() == 1) {
            // Special case handling, since if a URI is just length one
            // itself will never be a variable, so simply return true and itself
            // trailing slashes, if ever encountered will be kept as is
            return new StringFormatGroup.FormatResult(true, uri, uri);
        }
        List<PatternToken> current = roots;
        PatternToken matchedToken = null;
        for (final String slice : slices) {
            boolean matched = false;
            for (final PatternToken patternToken : current) {
                if (patternToken.isMatch(slice)) {
                    matchedToken = patternToken;
                    matched = true;
                    break;
                }
            }
            if (!matched) {
                return new StringFormatGroup.FormatResult(false, uri, uri);
            }
            current = matchedToken.children();
        }
        if (matchedToken.isLeaf()) {
            return new StringFormatGroup.FormatResult(true, uri, matchedToken.expression());
        } else {
            return new StringFormatGroup.FormatResult(false, uri, uri);
        }
    }
The pattern is split by /, and each token is a node in the tree. Each node either a literal string or "{var}"
representing a variable.

@param pattern of URIs
oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/config/group/uri/quickmatch/PatternTree.java