it seems like failed matches dont reset the captured group variables
There is no failed matches in there. Your regex matches the string fine. Although there are some failed matches for inner groups in some repetition. Each matched group might be overwritten by the next match found for that particular group, or keep it's value from previous match, if that group is not matched in current repetition.
Let's see how regex match proceeds:
First (a+)?(b+)?(c)
matches aac
. Since (b+)?
is optional, that will not be matched. At this stage, each capture group contains following part:
$1
contains entire match - aac
$2
contains (a+)?
part - aa
$3
contains (b+)?
part - null
.
$4
contains (c)
part - c
Since there is still some string left to match - bbbcac
. Proceeding further - (a+)?(b+)?(c)
matches - bbbc
. Since (a+)?
is optional, that won't be matched.
$1
contains entire match - bbbc
. Overwrites the previous value in $1
$2
doesn't match. So, it will contain text previously matched - aa
$3
this time matches. It contains - bbb
$4
matches c
Again, (a+)?(b+)?(c)
will go on to match the last part - ac
.
$1
contains entire match - ac
.
$2
matches a
this time. Overwrites the previous value in $2
. It now contains - a
$3
doesn't matches this time, as there is no (b+)?
part. It will be same as previous match - bbb
$4
matches c
. Overwrites the value from previous match. It now contains - c
.
Now, there is nothing left in the string to match. The final value of all the capture groups are:
$1
- ac
$2
- a
$3
- bbb
$4
- c
.
perl -E'"a"=~/(.)/; "b"=~/(..)/; say $1;'