Search code examples
javaregexvavr

Get regular expression groups with Vavr


Considering that Vavr provides tuples, is it possible to use them for capturing groups in regular expressions?

Taking an HTTP request line as an example string to match

GET /resource HTTP 1.1

and a matching pattern

Pattern.compile("(\\w+) (.+) (.+)")

are there methods in Vavr that return the three matched strings as a tuple?


Solution

  • It's easy to create this yourself:

    /**
     * Gets the three matched groups of the {@code regex} from the {@code original}.
     *
     * @param regex    a {@link Pattern} that should have three groups in it and
                       match the {@code original}
     * @param original the string we'll match with the {@code regex}
     * @return a {@link Tuple3} of the three matched groups or {@link Option#none} if
     *         the {@code regex} did not match
     */
    static Option<Tuple3<String, String, String>> getGroups3(Pattern regex,
                                                             CharSequence original) {
        var matcher = regex.matcher(original);
        return matcher.matches() && matcher.groupCount() == 3 ?
                Some(Tuple.of(matcher.group(1), matcher.group(2), matcher.group(3))) :
                Option.none();
    }
    

    This is how you could use the method:

    var pattern = Pattern.compile("(\\w+) (.+) (.+)");
    var requestLine = "GET /resource HTTP 1.1";
    
    var result = getGroups3(pattern, requestLine).fold(
            // No match
            () -> String.format("Could not parse request method, resource, and " +
                            "HTTP version from request line. Request line is '%s'",
                    requestLine),
            // Do whatever you want with the three matched strings
            tuple3 -> tuple3.apply((method, resource, httpVersion) ->
                    String.format("Method is %s, resource is %s, HTTP version is %s",
                            method, resource, httpVersion)));