The construct (.+|) will match one or more of any character (".+")or nothing ("|)"). So if no value is given there, the regex will match on nothing and return that into $a. Nothing in this case is the empty string, which is not equivalent to undef. To test for this you could test for truth instead of definedness (if($a)), but it'd be much better to specify the fact that $a is optional with the explicit "?", i.e. (.+)? instead of (.+|). The same goes for the other places where you use "|)".
Don't use the variables $a and $b like this, they are special variables (see perldoc perlvar) and you can run into strange errors when using them (or at least make your code hard to understand and maintain).
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan