Regular Expressions in Java
1. What is Regex?
A regular expression (regex) is a sequence of
characters that defines a search pattern. Regex engines scan input
text and identify portions that match the specified pattern. Java
provides built-in regex support through the
java.util.regex package, available
since JDK 1.4.
Common use cases include:
- Validation — verify that an email address, phone number, or postal code is correctly formatted.
- Search — locate one or more occurrences of a pattern within a larger string.
- Replace — substitute matched substrings with new content.
- Split — break a string into tokens using a delimiter pattern.
- Extract — pull out specific data (dates, prices, URLs) from unstructured text.
Note: Java regex syntax is largely compatible with Perl-style regular expressions, which are also used in Python, JavaScript, and most modern languages.
2. Key Classes
The java.util.regex package contains
three primary classes:
| Class | Role |
|---|---|
Pattern |
Compiled representation of a regex. Created via
Pattern.compile(regex).
Immutable and thread-safe; reuse instances for efficiency.
|
Matcher |
Engine that performs match operations on a character
sequence using a Pattern.
Created via
pattern.matcher(input). Not
thread-safe; create one per thread.
|
PatternSyntaxException |
Unchecked exception thrown when a regex pattern string has a
syntax error. Extends
IllegalArgumentException.
|
3. Basic Pattern Matching
The simplest workflow: compile a pattern, create a matcher for the
input, then call matches() to test
whether the entire input matches the pattern.
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class BasicMatch {
public static void main(String[] args) {
String pattern = "\\d{3}-\\d{4}"; // e.g. 555-1234
String input = "555-1234";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(input);
if (m.matches()) {
System.out.println("Input matches the pattern.");
} else {
System.out.println("No match.");
}
}
}
Warning:
matches() requires the entire string
to match. Use find() to locate a
pattern anywhere within the input.
4. Pattern Class
The Pattern class is the entry point
for all regex operations. Its key static and instance methods are:
compile()
Compiles the regex string into a reusable
Pattern object. Optionally accepts
flags such as
Pattern.CASE_INSENSITIVE.
Pattern p = Pattern.compile("[a-z]+", Pattern.CASE_INSENSITIVE);
matcher()
Creates a Matcher bound to the given
input string.
Matcher m = p.matcher("Hello World");
matches() — static shortcut
Compiles and matches in one call. Convenient for one-off checks.
boolean ok = Pattern.matches("\\d+", "12345"); // true
split()
Splits the input string around matches of the pattern — similar to
String.split() but with a pre-compiled
pattern.
Pattern p = Pattern.compile("[,;\\s]+");
String[] tokens = p.split("one, two; three four");
for (String t : tokens) System.out.println(t);
two
three
four
5. Matcher Class
A Matcher performs the actual
searching. Key methods:
find()
Advances through the input and returns
true each time a new match is found.
Ideal for iterating over all occurrences.
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("Order 42, item 7, qty 100");
while (m.find()) {
System.out.println("Found: " + m.group() + " at index " + m.start());
}
Found: 7 at index 15
Found: 100 at index 22
group(), start(), end()
After a successful find() or
matches(), these methods return the
matched substring, its start index, and its end index
respectively.
Pattern p = Pattern.compile("(\\w+)@(\\w+\\.\\w+)");
Matcher m = p.matcher("Contact: alice@example.com today.");
if (m.find()) {
System.out.println("Full match : " + m.group(0));
System.out.println("Username : " + m.group(1));
System.out.println("Domain : " + m.group(2));
System.out.println("Start/End : " + m.start() + " / " + m.end());
}
Username : alice
Domain : example.com
Start/End : 9 / 26
replaceAll()
Replaces every match in the input with the given replacement string.
String result = Pattern.compile("\\bfoo\\b")
.matcher("foo foobar foo")
.replaceAll("bar");
System.out.println(result);
6. Character Classes
Character classes match a single character against a set of allowed characters defined inside square brackets.
| Syntax | Meaning | Example Match |
|---|---|---|
[abc] |
Any one of a, b, or c |
"a",
"b",
"c"
|
[^abc] |
Any character except a, b, or c |
"d",
"z"
|
[a-z] |
Any lowercase letter a through z |
"m",
"p"
|
[A-Z] |
Any uppercase letter A through Z |
"G",
"T"
|
[0-9] |
Any digit 0 through 9 |
"3",
"7"
|
. |
Any character except newline |
"x",
"@",
"5"
|
7. Predefined Character Classes
Java regex provides shorthand escape sequences for common character groups.
| Shorthand | Meaning | Equivalent |
|---|---|---|
\d |
Any digit | [0-9] |
\D |
Any non-digit | [^0-9] |
\w |
Any word character (letter, digit, underscore) | [a-zA-Z0-9_] |
\W |
Any non-word character | [^a-zA-Z0-9_] |
\s |
Any whitespace (space, tab, newline) | [ \t\r\n\f] |
\S |
Any non-whitespace | [^ \t\r\n\f] |
In Java strings: backslash must be escaped, so
write \\d in a Java string literal
to represent the regex token \d.
8. Quantifiers
Quantifiers specify how many times a preceding element must occur to constitute a match.
| Quantifier | Meaning | Example Pattern | Matches |
|---|---|---|---|
* |
0 or more times | go* |
"g", "go", "goo", "gooo" |
+ |
1 or more times | go+ |
"go", "goo" (not "g") |
? |
0 or 1 time (optional) | colou?r |
"color", "colour" |
{n} |
Exactly n times | \d{4} |
"2024", "1999" |
{n,} |
At least n times | \d{2,} |
"12", "999", "10000" |
{n,m} |
Between n and m times | \d{2,4} |
"12", "123", "1234" |
By default, quantifiers are greedy — they match
as much as possible. Append ? to make
them lazy (e.g. .*?)
— match as little as possible.
9. Anchors and Boundaries
Anchors do not consume characters; they assert a position in the input string.
| Anchor | Asserts | Example |
|---|---|---|
^ |
Start of string (or start of line in MULTILINE mode) |
^Hello matches "Hello world" but
not "Say Hello"
|
$ |
End of string (or end of line in MULTILINE mode) |
world$ matches "Hello world" but
not "world peace"
|
\b |
Word boundary (between \w and \W) |
\bcat\b matches "cat" but not
"concatenate"
|
\B |
Non-word boundary |
\Bcat\B matches "concatenate"
but not standalone "cat"
|
Pattern p = Pattern.compile("^\\d{4}$");
System.out.println(p.matcher("2024").matches()); // true
System.out.println(p.matcher("20245").matches()); // false
System.out.println(p.matcher("abc").matches()); // false
false
false
10. Common Practical Examples
Email Validation
public static boolean isValidEmail(String email) {
String regex = "^[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,}$";
return Pattern.matches(regex, email);
}
System.out.println(isValidEmail("user@example.com")); // true
System.out.println(isValidEmail("bad-email@")); // false
System.out.println(isValidEmail("also.bad@.com")); // false
false
false
Phone Number Validation (US format)
public static boolean isValidPhone(String phone) {
// Accepts: (123) 456-7890, 123-456-7890, 1234567890
String regex = "^(\\(\\d{3}\\)\\s?|\\d{3}[-.]?)\\d{3}[-.]?\\d{4}$";
return Pattern.matches(regex, phone);
}
System.out.println(isValidPhone("(800) 555-1234")); // true
System.out.println(isValidPhone("800-555-1234")); // true
System.out.println(isValidPhone("8005551234")); // true
System.out.println(isValidPhone("1234")); // false
true
true
false
URL Pattern Extraction
String text = "Visit https://www.example.com or http://docs.java.net for more.";
Pattern p = Pattern.compile("https?://[\\w./-]+");
Matcher m = p.matcher(text);
while (m.find()) {
System.out.println("URL: " + m.group());
}
URL: http://docs.java.net
11. String Regex Methods
The String class provides convenient
regex shortcuts that do not require creating
Pattern or
Matcher objects explicitly.
matches()
Tests whether the entire string matches the given regex.
Equivalent to
Pattern.matches(regex, str).
String s = "hello123";
System.out.println(s.matches("[a-z]+\\d+")); // true
System.out.println(s.matches("[a-z]+")); // false (digits not covered)
false
replaceAll()
Replaces every substring matching the regex with the replacement.
Internally creates a new Pattern on
each call — cache a Pattern when
calling in a loop.
String cleaned = "Hello World !".replaceAll("\\s+", " ");
System.out.println(cleaned);
split()
Splits the string at each point where the regex matches, returning
a String[].
String csv = "apple, banana, cherry,date";
String[] fruits = csv.split(",\\s*");
for (String f : fruits) System.out.println(f);
banana
cherry
date
Performance tip:
String.replaceAll() and
String.split() recompile the pattern
on every invocation. If you call them repeatedly with the same
pattern, compile it once with
Pattern.compile() and reuse it.
