Please don't brainlessly use defined
on the list of values of $1, $2 etc, because you're now throwing away information about which pairs of parens were involved in the actual match. Sometimes that's what you want, but usually, it's not.
And eric256 has the right idea for using @- and/or @+ to find out how many paren pairs were involved.
You could use these arrays, one item per array, together with substr to extract the matches without symbolic references, but then you'd have to know what variable the match was against, and it may not have been changed in the meantime, for example by using the regexp in s///g, which would foul up the result. So I think the symbolic references for the captures for a reasonably elegant approach.