Regex guide
Regex match everything between brackets
The right bracket regex depends on whether the text has one pair, many pairs, or nested brackets.
Why bracket regexes overmatch
The pattern \[(.*)\] looks tempting, but .* is greedy. In alpha [one] beta [two], it can grab one] beta [two instead of stopping after one. That is why bracket extraction bugs often show up only after the second match appears in real data.
Example
alpha [one] beta [two]
\[(.*?)\] captures one and two as separate lazy matches.
Common bracket patterns
- Escape literal square brackets as \[ and \].
- Use \[(.*?)\] when you want the shortest match between one opening and one closing bracket.
- Use \[([^\]]*)\] when a closing bracket is not allowed inside the captured text.
- For nested brackets, switch to a parser or a regex engine with recursion support instead of stretching a flat pattern.
Greedy vs lazy matching
Greedy quantifiers grab as much text as they can. Lazy quantifiers stop as soon as the rest of the pattern can match. For a line with several bracketed chunks, lazy matching is usually closer to what you meant.
A negated character class is even stricter: it says "capture anything except the closing bracket." That makes the stopping rule obvious when bracket nesting is not allowed.
When regex is the wrong tool
Nested brackets, quoted strings, escaped brackets, and programming language syntax are where one-line regexes start to wobble. At that point, a parser is less clever and more reliable.
For log cleanup, keep the pattern narrow. If the bracketed value follows user= or tags=, include that label so the regex does not pick up an unrelated pair later in the line.
Common mistakes
- Forgetting to escape square brackets in the regex pattern
- Using greedy .* and capturing across several bracket pairs
- Expecting a basic regex to parse nested brackets reliably
- Testing only one example when production text contains multiple matches
Related problems
FAQ
What regex captures text inside square brackets?
Use \[(.*?)\] for a lazy match, or \[([^\]]*)\] when the captured text cannot contain a closing bracket.
Why does my regex match too much?
A greedy quantifier such as .* may run from the first opening bracket to the last closing bracket.
Can regex parse nested brackets?
Basic regex patterns are poor at nested structures. Use a parser when nested brackets matter.