No validation needed except with first word-word.
Using the \G anchor and a branch reset, will fill an array
where the words collect in capture group 1.
(?|(\w+)[ ]*-[ ]*(?=\w)|(?!^)\G[ ]*,?[ ]*(\w+))
https://regex101.com/r/deZq5u/1
Note no need for BOS or EOS anchor's which are crutches.
This will find valid matches mid-string as it should.
Formatted and tested
(Note the # Optional spaces, single comma, spaces will always match
either a space or a comma or both, even though optional, and is a required
separator. This is because the \w+ clause will not leave any behind.)
(?| # Branch reset
( \w+ ) # (1), First word
[ ]* - [ ]* # qualified with a dash,
(?= \w ) # then a lookahead for next word
| # or,
(?! ^ ) # Reset \G at BOS
\G # Anchor, second or more match
[ ]* ,? [ ]* # Optional spaces, single comma, spaces
( \w+ ) # (1), Second or more word
) # End branch reset
$3captures. Or, a PCRE solution will look uglier,(?:\G(?!^)|^(?=\w+ - (?:\w+[, ]{0,2})+$))\W*\K\w+.