Recommended Free Tools
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Java already supports named capture groups. For most applications, use java.util.regex.Pattern and Matcher; adding a dependency solely to retrieve captures by name solves no problem. Choose an alternative such as RE2/J only when you need its restricted syntax and predictable linear-time matching, or when compatibility with another regex flavor is a documented requirement.
Java named groups in one example
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Pattern email = Pattern.compile(
"(?<user>[A-Za-z0-9._%+-]+)@(?<domain>[A-Za-z0-9.-]+)"
);
Matcher matcher = email.matcher("[email protected]");
if (matcher.matches()) {
System.out.println(matcher.group("user")); // alice
System.out.println(matcher.group("domain")); // example.com
}
The regex form (?<name>...) captures text and assigns it a symbolic name. Java’s syntax and naming rules are documented in the Pattern API.
Declaration, retrieval and backreferences
Declare a group
(?<year>d{4})-(?<month>d{2})-(?<day>d{2})
In Java source, each regex backslash needs another backslash in the string literal:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Pattern date = Pattern.compile(
"(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})"
);
A group name must begin with a letter and may contain letters and digits. The Java documentation does not list underscore as a valid character, so prefer username to user_name.
#1 Best Overall
- Used Book in Good Condition
Read the value and its offsets
if (matcher.find()) {
String value = matcher.group("domain");
int start = matcher.start("domain");
int end = matcher.end("domain");
}
group("name")returns the captured text.start("name")andend("name")return character offsets.group()orgroup(0)returns the complete match.- Calling a group accessor before a successful
find()ormatches()throws an exception.
matches() requires the entire input to match; find() searches for the next matching subsequence. The named accessors are also available through MatchResult.
Named backreferences
Pattern repeated = Pattern.compile("(?<word>\w+)\s+\k<word>");
k<word> requires the same text captured by word. Do not confuse it with replacement syntax, described below.
Names do not remove numeric groups
Named groups are still numbered from left to right; group zero is always the complete match.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →| Number | Name | Value for 2026-09 |
|---|---|---|
| 0 | — | 2026-09 |
| 1 | date | 2026-09 |
| 2 | year | 2026 |
| 3 | month | 09 |
(?<date>(?<year>d{4})-(?<month>d{2}))
Use names in application code because inserting an earlier capturing parenthesis can shift every later number. Numeric access remains useful for generic tooling.
Rank #2
Optional and repeated captures
Pattern url = Pattern.compile("(?<scheme>https?://)?(?<host>[^/]+ ");
Matcher m = url.matcher("example.com");
if (m.matches()) {
String scheme = m.group("scheme"); // null
String host = m.group("host"); // example.com
}
An optional group that did not participate returns null; check it before calling methods such as toLowerCase().
A quantified group stores only the capture from its most recent successful iteration. It is not a collection of captures. To collect every item, match repeatedly:
Pattern tag = Pattern.compile("(?<tag>\w+)");
Matcher tags = tag.matcher("red blue green");
while (tags.find()) {
list.add(tags.group("tag"));
}
Group names also cannot be reused in one Java pattern.
Named groups in replacements
Pattern backreferences and replacement references use different syntaxes:
Rank #3
k<name>is a backreference inside the regex.${name}refers to a named group in a replacement string.
Pattern person = Pattern.compile("(?<first>\w+)\s+(?<last>\w+)");
String result = person.matcher("Ada Lovelace")
.replaceAll("${last}, ${first}");
// Lovelace, Ada
See the Matcher documentation for replacement rules.
Modern Java version note
| Feature | Version guidance |
|---|---|
Named declaration and group(String) |
Available since Java 7-era releases and later |
Pattern.namedGroups() |
Java 20 |
| Java SE 26 API reference | Documentation for JDK 26 |
namedGroups() returns an unmodifiable map from names to group numbers. It is useful for introspection, but it raises the minimum JDK for that code; ordinary named matching does not require Java 20.
Pattern p = Pattern.compile("(?<year>\d{4})-(?<month>\d{2})");
System.out.println(p.namedGroups()); // Java 20+
Is a third-party regex engine better?
Only for a different requirement. Java’s built-in engine provides lookarounds, backreferences, possessive quantifiers, atomic groups and Java’s Unicode options without a deployment change. It is the default for trusted, reviewed patterns and normal parsing, validation and extraction.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →RE2/J: choose safety over full Java syntax
RE2 is designed for predictable, linear-time matching; RE2/J is its pure-Java port. It supports named captures and a familiar API:
<dependency>
<groupId>com.google.re2j</groupId>
<artifactId>re2j</artifactId>
<version>1.8</version>
</dependency>
import com.google.re2j.Matcher;
import com.google.re2j.Pattern;
Pattern p = Pattern.compile("(?<user>[A-Za-z0-9._%+-]+)@(?<domain>[A-Za-z0-9.-]+)");
Matcher m = p.matcher("[email protected]");
if (m.matches()) {
System.out.println(m.group("user"));
}
Use RE2/J when patterns or inputs may be user-controlled and a restricted regular-expression language is acceptable. It intentionally omits backreferences, lookahead, lookbehind, atomic groups and possessive quantifiers. A Java pattern using those features is not a drop-in migration. RE2’s syntax reference lists supported and unsupported constructs.
Linear-time design is a safety property, not a promise of lower latency for every workload; benchmark representative inputs and retain input-size limits.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.JRegex and Joni: compatibility choices, not upgrades
JRegex uses nonstandard named-group syntax such as ({Name}REGEX). Consider it only when maintaining an existing JRegex codebase, and verify its current Java support and maintenance before deployment.
Joni is an Oniguruma-style engine used in some Ruby/JRuby ecosystems. It can be justified by an existing Ruby-compatible syntax requirement, but it should not be presented as a general replacement for java.util.regex. Test the exact version and constructs you need.
Best Value
Apache Commons Lang is a utility library, not a replacement regex engine.
Feature and decision comparison
| Requirement | Choice | Reason |
|---|---|---|
| Named groups, no dependency | java.util.regex |
Built into the JDK |
| Lookarounds or backreferences | java.util.regex |
RE2/J omits them |
| User-supplied patterns or hostile input | Evaluate RE2/J | Restricted syntax and linear-time design |
| Ruby/Oniguruma compatibility | Joni | Compatibility may justify the dependency |
| Legacy JRegex application | JRegex | Avoid needless migration |
| Nested or highly structured grammar | Parser | Regex may be the wrong abstraction |
| Feature | java.util.regex |
RE2/J |
|---|---|---|
| Named capture and retrieval | Yes | Yes |
| Lookahead/lookbehind | Yes | No |
| Backreferences | Yes | No |
| Possessive quantifiers/atomic groups | Yes | No |
| General linear-time guarantee | No | Designed for it |
| Extra dependency | No | Yes |
Security, portability and testing
Named groups do not make a pattern safe. Backtracking patterns can exhibit excessive work with adversarial input. Bound input length, avoid nested ambiguous quantifiers, impose execution/resource limits where your architecture allows it, and test hostile cases. If the required syntax fits, RE2/J is worth evaluating for untrusted patterns.
Do not assume similar-looking flavors behave identically. Test named syntax ((?<name>...) and, where supported, (?P<name>...)), Unicode classes, word boundaries, case folding, empty matches, replacement syntax and error behavior in the exact engine and version you deploy. Java’s w, b and . should be tested against the languages your application accepts.
Free tools Windows power users keep installed
One-click scans. No signup required.
A practical test matrix includes: successful and failed matches; find() versus matches(); absent optional groups; repeated captures; named backreferences; invalid, duplicate or digit-leading names; named replacements; Java escaping; lookarounds and backreferences; large adversarial inputs; and the same corpus run through both engines before migration.
Bottom line
Use java.util.regex for named groups in ordinary Java code. The syntax is stable, the APIs are standard, and no library is needed. Add RE2/J only when predictable behavior on untrusted patterns outweighs Java’s advanced features. Treat JRegex and Joni as narrowly justified compatibility dependencies, not as better ways to name captures.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

