Before this lesson
Understand character classes and anchors. Be ready to compare several matching results.
What you will be able to do
Control repetition and understand greedy versus lazy selection.
Understand the mechanism
* means zero or more, + one or more, ? zero or one, and {m,n} bounds repetition. A quantifier applies to the immediately preceding atom or group, not the entire pattern.
Greedy quantifiers first try more characters; a following ? makes a quantifier lazy, initially trying fewer. Both are constrained by the remaining pattern. Lazy does not mean no backtracking or automatically faster.
For content that cannot contain a closing bracket, an explicit negated class expresses the boundary more directly than .*. This exercise handles flat labels, not nested brackets or HTML.
Runnable example
const text = "[one] [two]";
console.log(JSON.stringify(text.match(/\[.*\]/g)));
console.log(JSON.stringify(text.match(/\[.*?\]/g)));
console.log(JSON.stringify(text.match(/\[[^\]\r\n]+\]/g)));
console.log(JSON.stringify(["", "a", "aaaa"].map(s => /^a{1,3}$/.test(s))));
Trace and verify
The greedy pattern spans from the first opening bracket to the final closing bracket. The other patterns return separate one and two labels. Repetition 1 to 3 rejects both empty input and four a characters.
Common mistakes and boundaries
.*? can still match empty content. Decide explicitly whether [] is valid, and whether a negated class should permit newlines.
Practice challenge
Modify the third pattern to allow an empty [] label.
Reference solution and reasoning
Replace + after the negated class with *. Both [] and [one] match, while line breaks remain excluded.