Regular expressions in Java
Pattern, Matcher, groups, matches vs find, common regex pitfalls.
"a.b.c".split(".") — three parts, obviously? Java says the array has length 0. The dot is not what it seems…A pattern for text
A regex describes text shapes: **\d a digit, \w a word character, + one or more, . *any* character. Compile once with Pattern.compile, then create a Matcher for each text. In Java strings the backslash is doubled: "\\d"**.
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("order 66");matches vs find
**matches() succeeds only if the entire input** fits the pattern (String.matches too). **find() searches for the next match anywhere** in the text.
Whole or part?
What does this print?
String s = "abc123";
System.out.println(s.matches("[a-z]+"));
System.out.println(Pattern.compile("[a-z]+")
.matcher(s).find());true truefalse truefalse false
Show the answer
false — "abc123" isn't made *only* of letters. true — find spots "abc" inside it.
Groups capture pieces
Parentheses create groups, numbered by their opening parenthesis, left to right. **group(0)** is the whole match, group(1) the first ( ), and so on.
var p = Pattern.compile("(\\d{4})-(\\d{2})");
var m = p.matcher("Due 2024-07");
if (m.find()) {
m.group(1); // "2024"
m.group(2); // "07"
}Which group?
What does this print?
var p = Pattern.compile("(\\d+)-(\\d+)");
var m = p.matcher("call 555-1234 now");
if (m.find()) {
System.out.println(m.group(2));
}5551234555-1234
Show the answer
1234 — group 1 is "555", group 2 is "1234", and group 0 would be the whole "555-1234".
Greedy stars
.* is greedy: it grabs as much as possible, from the first < to the last > — swallowing "hi" too, so this prints an empty line. Use reluctant **<.*?> or <[^>]+>** to match one tag at a time.
String html = "<b>hi</b>";
html.replaceAll("<.*>", ""); // ""
html.replaceAll("<[^>]+>", ""); // "hi"Splitting on a dot
"a.b.c".split(".").length // 0. matches any character, so every char is a separator; the pieces are all empty and trailing empties are removed.
"a.b.c".split("\\.") // [a, b, c]\\. in Java source means the regex \.: a literal dot.
Regex on the job
Validating input, parsing log lines, extracting IDs from URLs — regex is everywhere. Teams compile patterns once into static final Pattern constants (compiling is costly) and treat greedy .* and unescaped dots as code-review red flags.
Key takeaways
- matches(): whole string; find(): any part of it
- group(0) is the whole match; group(1) the first ( )
- In Java strings, \d must be written "\\d"
- split(".") is a regex: escape it as "\\."
Regular expressions were invented in the 1950s by mathematician Stephen Kleene — the * operator is still called the "Kleene star".
Practice questions
What does this print?
String s = "order 66";
System.out.println(s.matches("\\d+"));
System.out.println(
Pattern.compile("\\d+").matcher(s).find());- true true
- false true
- true false
- false false
Check your answer
false true. "order 66" is not made entirely of digits, so matches is false. find succeeds because "66" appears inside it.
What does this print?
Pattern p = Pattern.compile("(\\w+)@(\\w+)\\.com");
Matcher m = p.matcher("mail [email protected] now");
if (m.find()) {
System.out.println(m.group(2));
}- ana
- site
- [email protected]
- com
Check your answer
site. Groups are numbered by their opening parenthesis from left to right: group(1) is "ana", group(2) is "site". group(0) is the whole match.