Well, here's how I would do it; this regex will populate $1 with the sigil, and $2 with the name if it is a variable like "$foo"; in the "<foo>" case, $1 will be undef and $2 will contain the name.
/
^ # start
(?:([\$\@\*\%])|<) # leading sigil or <
(\w+) # name
(?(?{$1}) |> ) # if there was a leading sigil, match nothing;
# otherwise, match >
$ # end
/x;
Another way might be to use this one:
/
^ # start
([\$\@\*\%<]) # sigil
(\w+) # name
(?(?{$1 eq '<'}) >| ) # if the sigil is a '<', match the end;
# otherwise match nothing
$ # end
/x;
This is different in that in the "<foo>" case, $1 will be '<'.
In either case, theres no real reason to capture $3, since there is only one possibility that it could be(>), and you will know if the possibility is true or not depending on $1.