È necessario un'espressione che abbinerà solo caratteri dagli stessi unicode script (e spazi), come:
^([\p{SomeScript} ]+|[\p{SomeOtherScript} ]+|...)$
È possibile costruire questa espressione in modo dinamico dalla lista degli script:
$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
Si noti tuttavia che è comune per i nomi (almeno negli script europei che conosco) includere caratteri come punti, trattini e apostrofi, che appartengono allo script "Comune" piuttosto che a uno specifico della lingua. Per tenerne conto, una versione più realistica di un "pezzo" nella espressione di cui sopra potrebbe essere simile a questo:
((\p{SomeScript}+(\. ?|[ '-]))*\p{SomeScript}+)
che sarà almeno la convalida correttamente L. A. Léon de Saint-Just
.
In generale, la convalida dei nomi delle persone è un problema complesso e non può essere risolta con una precisione del 100%. Vedi this funny post e commenti al riguardo per dettagli ed esempi.
che ne dici di usare \ w \ s + \ w – SolidSnake
Questa è una domanda interessante. Non funziona per alcune delle lingue che definisci nella regex? –