Unravel โบ Java concepts โบ Strings and text
Regular expressions
A regular expression describes a pattern of text.
At a glance
A stencil with holes: you slide it over text and it lights up everything that fits, such as "three digits, a dash, four digits".
- 1Pattern p = Pattern.compile("(\\d{3})-(\\d{4})"); Matcher m = p.matcher(text); builds the pattern oncem.find() looks for the next match; m.group(1) reads a captured part.
- 2matches() requires the whole string to match; find() looks for a match anywhere; lookingAt() anchors at the start
- 3Backslashes must be doubled in Java string literals: the regex \\d is written "\\d"Text blocks and raw patterns make this easier to read.
- 4String.replaceAll(regex, replacement) and split(regex) take a regex, not plain text; special characters such as and + must be escaped, or use Pattern.quote.
- Compile patterns once and keep them in a static final field
- Some patterns take exponential time on certain inputs (catastrophic backtracking), for example nested quantifiers like (a+)+$
- Java's engine compiles the pattern into a graph of nodes and matches by backtracking: on failure it returns to the last choice point and tries another path
private static final Pattern ORDER_ID = Pattern.compile("ORD-(?<year>\\d{4})-(?<seq>\\d+)");static Optional<String> yearOf(String text) { Matcher m = ORDER_ID.matcher(text); return m.find() ? Optional.of(m.group("year")) : Optional.empty();}- line 1 uses Pattern, the core of Regular expressions
- line 4 uses Matcher, the core of Regular expressions
- line 5 uses find, the core of Regular expressions
Read the full explanation (about 2 min)
A regular expression describes a pattern of text. In Java you compile it into a Pattern, run it against text with a Matcher, and read what matched. String.matches and replaceAll are shortcuts for one-off use.
A mental model
A stencil with holes: you slide it over text and it lights up everything that fits, such as "three digits, a dash, four digits".
How it works
Pattern p = Pattern.compile("(\\d{3})-(\\d{4})"); Matcher m = p.matcher(text); builds the pattern once. m.find() looks for the next match; m.group(1) reads a captured part.
matches() requires the whole string to match; find() looks for a match anywhere; lookingAt() anchors at the start.
Backslashes must be doubled in Java string literals: the regex \\d is written "\\d". Text blocks and raw patterns make this easier to read.
String.replaceAll(regex, replacement) and split(regex) take a regex, not plain text; special characters such as . and + must be escaped, or use Pattern.quote.
Going deeper
Compile patterns once and keep them in a static final field. String.matches and replaceAll recompile on every call, which is slow in a loop.
Some patterns take exponential time on certain inputs (catastrophic backtracking), for example nested quantifiers like (a+)+$. On user-supplied text this is a denial-of-service risk; keep patterns simple and bound the input length.
Regex is the wrong tool for nested structures such as HTML, JSON or code. Use a parser for those.
Name your groups ((?<year>\\d{4})) and read them with m.group("year") so the code survives a change to the pattern.
Under the hood
Java's engine compiles the pattern into a graph of nodes and matches by backtracking: on failure it returns to the last choice point and tries another path. That is simple and powerful, and also the reason bad patterns can blow up.
Common mistakes
- Forgetting to double backslashes.
- Compiling a pattern inside a loop.
- Using
matcheswhenfindis meant (it needs the whole string). - Splitting on
.or|without escaping. - Running an unbounded pattern on untrusted input.
How Unravel recognises it
When you paste code, Unravel looks for these signs of regular expressions. Spotting them yourself is a good habit when you read unfamiliar code:
- Types:
PatternMatcherPatternSyntaxException - Method calls:
Pattern.compile()Pattern.matches()replaceAll()replaceFirst()matches()find()group()
Part of a learning path
Related concepts
Frequently asked questions
What is Regular expressions?
A regular expression describes a pattern of text. In Java you compile it into a Pattern, run it against text with a Matcher, and read what matched. String.matches and replaceAll are shortcuts for one-off use.
What are the most common mistakes with Regular expressions?
Forgetting to double backslashes. Compiling a pattern inside a loop. Using matches when find is meant (it needs the whole string). Splitting on . or | without escaping. Running an unbounded pattern on untrusted input.
How can I see Regular expressions in real code?
Paste your own Java into Unravel and it will point out where regular expressions appears, explain how it works at the detail level you choose, and draw the flow of the code around it.