仅匹配相同语言的字符集(如Facebook名称)?

new*_*ewz 10 php regex unicode preg-match

preg_match(???, 'firstname lastname') // true;
preg_match(???, '?? ??') // true;
preg_match(???, '?? lastname') // false;
preg_match(???, '#$@ #$$#') // false;
Run Code Online (Sandbox Code Playgroud)

目前我使用:

'/^([?-?0-9\s]+|[?-?0-9\s]+|[?-?0-9\s]+|[?-??0-9\s]+|[a-zA-Z0-9\s]+|[???0-9\s]+)$/u'
Run Code Online (Sandbox Code Playgroud)

但它只适用于某些语言.

geo*_*org 7

您需要一个只匹配相同unicode脚本(和空格)的字符的表达式,如:

 ^([\p{SomeScript} ]+|[\p{SomeOtherScript} ]+|...)$
Run Code Online (Sandbox Code Playgroud)

您可以从脚本列表中动态构建此表达式:

$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, '#$@ #$$#'); // 0
Run Code Online (Sandbox Code Playgroud)

确实注意到然而,这是很常见的名字(至少在欧洲剧本我很熟悉),包括像点,破折号和省略号,属于"公共"的脚本,而不是特定语言的一个字符.考虑到这些因素,上面表达式中"块"的更真实版本可能是这样的:

 ((\p{SomeScript}+(\. ?|[ '-]))*\p{SomeScript}+)
Run Code Online (Sandbox Code Playgroud)

这将至少正确验证L. A. Léon de Saint-Just.

一般来说,验证人名是一个复杂的问题,不能100%准确地解决.有关详细信息和示例,请参阅此有趣的帖子和评论.