Regular expressions

Core Java · lesson 32 of 42 · 4 min read

Match, split and replace text with java.util.regex instead of hand-rolling a parser.

Open this lesson in the learning hub

Key points

  • "text".matches(re) must match the whole string; Matcher.find() looks for a match anywhere.
  • Compile once with Pattern.compile and reuse it. A Pattern is thread-safe, a Matcher is not.
  • Groups: (...) captures, m.group(1) reads it back, and (?<name>...) gives it a name.
  • Quantifiers are greedy: <.+> swallows to the last bracket, while <.+?> stops at the first.
  • Alternation a|b|c is ordered — the leftmost branch that fits wins, so put the specific one first.
  • Every backslash is doubled inside a Java string, so the regex \d is written "\\d".

Example

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

    static String firstMatch(String regex, String input) {
        Matcher m = Pattern.compile(regex).matcher(input);
        return m.find() ? m.group() : "(none)";
    }

    public static void main(String[] args) {
        System.out.println("matches whole input : " + "2024-05-17".matches("\\d{4}-\\d{2}-\\d{2}"));
        System.out.println("partial match       : " + "id 2024 x".matches("\\d{4}") + " (use find instead)");
        System.out.println("split on commas     : " + Arrays.toString("a, b ,c".split("\\s*,\\s*")));
        System.out.println("replaceAll digits   : " + "a1b22c".replaceAll("\\d+", "#"));

        Pattern email = Pattern.compile("(\\w+)@(\\w+)\\.com");   // compile once, reuse
        Matcher m = email.matcher("write to ada@example.com or linus@kernel.com");
        while (m.find()) {
            System.out.println("found " + m.group() + "  user=" + m.group(1) + "  host=" + m.group(2));
        }

        Matcher named = Pattern.compile("(?<key>[a-z]+)=(?<value>\\d+)").matcher("port=8080");
        System.out.println("named groups        : "
                + (named.matches() ? named.group("key") + " -> " + named.group("value") : "no match"));

        System.out.println("greedy  <.+>  on <a><b> : " + firstMatch("<.+>", "<a><b>"));
        System.out.println("lazy    <.+?> on <a><b> : " + firstMatch("<.+?>", "<a><b>"));
        System.out.println("alternation is ordered  : " + firstMatch("cat|dog|bird", "a dog and a bird"));
    }
}

Compile the pattern once, and remember matches() means the entire string.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Core Java course, and every lesson in it is listed on the Core Java contents page.