Here is one possible answer:
(?:^|, *)(?![^",]+")(?:((?=[^"<]+@)|(?![^"<]+@)"?(?<name>[^"<]*)"? *))<?(?<email>[^,>]*)>?
This is using ruby regexes, and uses forward matches to determine if an entry has a name.
(?:^|, *): start at the front of the string, or after a , and a number of spaces
(?![^",]+"): negative lookahead, abort match if there are some characters and then a ". This stops commas from starting matches inside strings.
(?:((?=[^"<]+@)|(?![^"<]+@)"?(?<name>[^"<]*)"? *)): matching the name:
(?=[^"<]+@) if a @ occurs before a quote or open brace, it is just a email address without name, so do no match
(?![^"<]+@)"?(?<name>[^"<]*)"? *): otherwise, match the name (skipping the open and close quote if they are present
<?(?<email>[^,>]*)>?: match the email.
On rubular
Note that for a real job, this would be a terrible approach. The regex is near incomprehensible, not to mention fragile. It also isn't complete, eg what happens if you can escape quotes inside the name?
I would write a dedicated parser for this if you really need it. If you are just trying to extract some data though, the regex may be good enough.