Pattern compiles a regular expression, while Matcher holds the mutable state of a match attempt against one input.
Java regular expressions: full matches, searches and capture boundaries
Java 8+. This is a complete program using JDK classes.
Define the accepted record
A parcel identifier in this application has two ASCII capital letters, a hyphen, and four digits. matches() asks whether the whole input has that form. find() asks a different question: whether some region matches. Using a successful search as full validation lets surrounding junk cross the boundary.
The compiled Pattern can be reused. A Matcher should belong to one operation rather than a shared service field, because its cursor, region and captured groups change. Query a group only after a successful matching operation; a failed match does not supply a previous success as a safe fallback.
The alphabet is intentional. The program uses [0-9] because the wire format names ASCII digits, and it keeps the original spelling. More permissive Unicode or case-insensitive options need tests for the chosen format. A short identifier rule should not silently become a general international-text validator.
Keep worst-case inputs in the review
Not every expression has the same runtime behavior. Nested ambiguous repetition can force extensive backtracking. Bound the input, prefer an unambiguous grammar for machine records, and test rejected long strings. Precompiling reduces repeated compilation; it does not repair the complexity of the chosen expression.
Working program
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class ParcelIdentifierPattern {
private static final Pattern ID = Pattern.compile("([A-Z]{2})-([0-9]{4})");
public static void main(String[] args) {
Matcher exact = ID.matcher("DL-0042");
if (exact.matches()) System.out.println(exact.group(1) + ":" + exact.group(2));
System.out.println(ID.matcher("prefix DL-0042 suffix").matches());
Matcher search = ID.matcher("prefix DL-0042 suffix");
System.out.println(search.find());
}
}Output
DL:0042
false
trueCosts and boundaries
This fixed-length rule has bounded work for the accepted record and rejects overlong whole inputs. Do not infer a linear-time guarantee for arbitrary Java regular expressions from this example. Pattern storage is reusable; each Matcher adds per-operation state.
Common Mistakes
- A successful find is not full-input validation.
- A shared Matcher introduces mutable state between requests.
- Escaping has two layers when a regex is written in a Java string.
