By WebNest Studio Engineering Team
Java - Core Tutorial
Java Regular Expressions (Regex)
A regular expression (regex) is a pattern that describes a set of matching strings, and Java provides full regex support through the java.util.regex package as well as several regex-powered methods directly on the String class. Regex is the standard tool for validating input formats (emails, phone numbers, postal codes), searching text, and performing pattern-based replacements.
Why it matters
Regular expressions describe a text pattern in one line: a valid phone number, a date, every number in a log line. They are how input is validated and text is extracted in most real applications. They are also easy to get subtly wrong, so it pays to know exactly what matches() checks and how backslashes are written inside a Java string.
The Pattern and Matcher Classes
Pattern.compile(regex) compiles a regular expression string into a reusable Pattern object — compiling once and reusing the Pattern is more efficient than recompiling the same regex repeatedly. Calling pattern.matcher(input) produces a Matcher object bound to a specific input string, which provides methods like matches() (does the entire input match the pattern), find() (is there a matching subsequence anywhere in the input), and group() (retrieve the text that matched).
Common Regex Metacharacters
A small set of metacharacters covers the vast majority of everyday patterns.
.— matches any single character (except line terminators by default).*and+— zero-or-more and one-or-more repetitions of the preceding element.?— zero-or-one occurrence (also used to make a quantifier non-greedy, as in*?).\dand\w— a single digit (0-9) and a single "word" character (letters, digits, underscore) respectively.^and$— anchor a match to the start and end of the input (or line, in multiline mode).
Regex-Powered String Methods
You rarely need Pattern and Matcher directly for simple cases, because String itself exposes convenient regex-based methods: matches(regex) checks whether the entire string matches a pattern, replaceAll(regex, replacement) replaces every matching subsequence, and split(regex) breaks a string into an array wherever the pattern matches. These cover most validation and parsing needs without ever constructing a Pattern object explicitly.
Example
Validating an email-like format and using replaceAll
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo {
public static void main(String[] args) {
String email = "user@example.com";
String regex = "^[\\w.]+@[\\w]+\\.[a-zA-Z]{2,}$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(email);
System.out.println(matcher.matches());
System.out.println(email.matches(regex));
System.out.println("2026-09-21".replaceAll("-", "/"));
}
}
true
true
2026/09/21
Common Mistakes
- Forgetting that in a Java string literal, backslashes in a regex must be escaped, so "\d" must be written as "\\d" in source code.
- Using matches() when find() was intended (or vice versa) — matches() requires the entire input to match the pattern, while find() looks for a matching subsequence anywhere within it.
- Recompiling the same regex with Pattern.compile() inside a loop instead of compiling it once outside the loop and reusing the Pattern object.
- Writing an overly permissive email or input validation regex and assuming it covers every valid real-world case — production validation often needs additional checks beyond a single regex.
Exercise
Validate an Indian PIN code: it must be exactly six digits and must not start with 0.
Expected output: true for 110001, false for 012345, and false for 1100.
public class PinCode {
static boolean isValidPin(String pin) {
// TODO: return true only for six digits where the first is 1-9
return false;
}
public static void main(String[] args) {
System.out.println(isValidPin("110001"));
System.out.println(isValidPin("012345"));
System.out.println(isValidPin("1100"));
}
}
Show hints
[1-9]matches one digit that is not zero, and[0-9]{5}matches exactly five more digits.String.matches(regex)is true only when the whole string fits the pattern.
Show solution
public class PinCode {
static boolean isValidPin(String pin) {
return pin.matches("[1-9][0-9]{5}");
}
public static void main(String[] args) {
System.out.println(isValidPin("110001")); // true
System.out.println(isValidPin("012345")); // false
System.out.println(isValidPin("1100")); // false
}
}
Quick quiz
1. In the Java string "\\d", what does the regular expression match?
- A. The letter d
- B. A backslash followed by d
- C. Any character
- D. Any single digit
Show answer
D. The two backslashes in the Java source produce one backslash in the actual string, giving the regex \d, which matches a digit.
2. What does "a1b22".replaceAll("[0-9]+", "#") return?
- A. a#b#
- B. a#b##
- C. #
- D. a1b22
Show answer
A. The + makes each run of digits a single match, so "1" and "22" are each replaced by one #.
3. What must be true for String.matches(regex) to return true?
- A. The pattern occurs somewhere in the string
- B. The entire string matches the pattern
- C. The string starts with the pattern
- D. The string ends with the pattern
Show answer
B. matches() tests the whole string. To look for the pattern anywhere inside the text, use a Matcher and find().
Interview questions
What is the difference between matches() and find() on a Matcher?
Show answer
matches() returns true only if the entire input matches the pattern. find() searches for the next part of the input that matches, and can be called repeatedly to walk through every occurrence. Validation of a whole value uses matches(); searching and extracting uses find().
Why compile a Pattern once instead of calling String.matches() repeatedly?
Show answer
String.matches(), replaceAll() and split() compile the regular expression every time they are called. In a loop or a frequently called method that is wasted work. Compiling it once with Pattern.compile(), typically into a static final field, and reusing the Pattern avoids the repeated compilation. A Pattern is immutable and safe to share between threads.
Key Points to Remember
- java.util.regex provides Pattern (a compiled expression) and Matcher (matching logic bound to specific input text).
- Key metacharacters: . * + ? \d \w ^ $ cover most common patterns.
- String offers built-in regex methods: matches(), replaceAll(), and split().
- Compile a Pattern once and reuse it rather than recompiling the same regex repeatedly for performance.
Practice in the playground
Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.
Run the examples
Change an input, predict the result, then compare it with the output. Explain why the result changes.
Written by
WebNest Studio Engineering Team
Practical lessons from developers working with Java, Python, React, databases and production systems.
Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering