Попробуйте это:
/^(([A-Za-z]+[\-\']?)*([A-Za-z]+)?\s)+([A-Za-z]+[\-\']?)*([A-Za-z]+)?$/
Необязательно [по крайней мере 1 алфавитный символ, за которым следует 'или -] неограниченное количество раз.Перед обязательным пробелом должен быть хотя бы один алфавитный символ, чтобы мы могли получить хотя бы имя и фамилию.Весь этот шаблон сгруппирован так, чтобы принимать неопределенное повторение (для людей, которые любят использовать все свои имена, таких как Джон Джейкоб Джинглхаймер Шмидт), но должен появляться хотя бы один раз, с помощью знака + прямо посередине.Наконец, фамилия обрабатывается так же, как и другие имена, но завершающий пробел не допускается.(К сожалению, это означает, что мы немного нарушаем DRY.)
Вот результат на нескольких возможных фрагментах ввода:
"Jon Doe": true
"Jonathan Taylor Thomas": true
"Julia Louis-Dreyfus": true
"Jean-Paul Sartre": true
"Pat O'Brien": true
"Þór Eldon": false
"Marcus Wells-O'Shaugnessy": true
"Stephen Wells-O'Shaugnessy Marcus": true
"This-Is-A-Crazy-Name Jones": true
"---- --------": false
"'''' ''''''''": false
"'-'- -'-'-'-'": false
"a-'- b'-'-'-'": false
"'-'c -'-'-'-d": false
"e-'f g'-'-'-h": false
"'ij- -klmnop'": false
Обратите внимание, что он по-прежнему не обрабатывает символы Unicode, новозможно, его можно расширить, включив при необходимости.