Ответ 1
Вам нужно выражение, которое будет соответствовать только символам из тех же unicode script (и пробелов), например:
^([\p{SomeScript} ]+|[\p{SomeOtherScript} ]+|...)$
Вы можете построить это выражение динамически из списка скриптов:
$scripts = "Hangul Hiragana Han Latin Cyrillic"; // feel free to add more
$re = [];
foreach(explode(' ', $scripts) as $s)
$re [] = sprintf('[\p{%s} ]+', $s);
$re = "~^(" . implode("|", $re) . ")$~u";
print preg_match($re, 'firstname lastname'); // 1
print preg_match($re, '서프 누워'); // 1
print preg_match($re, '서프 lastname'); // 0
print preg_match($re, '#[email protected] #$$#'); // 0
Обратите внимание, что это общепринято для имен (по крайней мере, в европейских сценариях, с которыми я знаком), чтобы включать символы, такие как точки, тире и апострофы, которые относятся к "Common" script, а не к языку -специфический. Чтобы принять это во внимание, более реалистичная версия "куска" в приведенном выше выражении может быть примерно такой:
((\p{SomeScript}+(\. ?|[ '-]))*\p{SomeScript}+)
который будет хотя бы корректно проверять L. A. Léon de Saint-Just
.
В целом, проверка имен людей является сложной проблемой и не может быть решена с точностью 100%. См. этот смешной пост и комментарии к нему для деталей и примеров.