The ?
reluctant quantifier makes .*
match as few characters as possible, only matching more character if it's required by backtracking.
Here's an illustrative example of using regex to find a non-empty prefix that is also a suffix of a string (no overlapping).
The capturing group \1
in the first pattern is greedy: it first matches everything, and takes as less as it backtracks. As such, the pattern will find the longest possible prefix/suffix match:
System.out.println(
"abracadabra".replaceAll("^(.+).*\\1$", "($1)")
); // prints "(abra)"
Now \1
in the second pattern is reluctant; it first matches nothing, and takes more as it backtracks. As such, the pattern will find the shortest prefix/suffix match:
System.out.println(
"abracadabra".replaceAll("^(.+?).*\\1$", "($1)")
); // prints "(a)"
In your case, the .*?
can match an empty string, and never needed to backtrack and match more since it was enough for the overall pattern to match.
See also
Here's another illustrative example of reluctant quantifier on a finite repetition:
Here, x{3,5}
is greedy, and will take as much as possible.
System.out.println(
"xxxxxxx".replaceAll("x{3,5}", "Y")
); // prints "Yxx"
Here, x{3,5}?
is reluctant, and will take as few as possible.
System.out.println(
"xxxxxxx".replaceAll("x{3,5}?", "Y")
); // prints "YYx"