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

时间:2014-09-28 23:37:41

标签: php regex unicode preg-match

preg_match(???, 'firstname lastname') // true;
preg_match(???, '서프 누워') // true;
preg_match(???, '서프 lastname') // false;
preg_match(???, '#$@ #$$#') // false;

目前我使用:

'/^([一-龠0-9\s]+|[ぁ-ゔ0-9\s]+|[ก-๙0-9\s]+|[ァ-ヴー0-9\s]+|[a-zA-Z0-9\s]+|[々〆〤0-9\s]+)$/u'

但它只适用于某些语言。

1 个答案:

答案 0 :(得分:7)

您需要一个只匹配相同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, '#$@ #$$#'); // 0

请注意,名称(至少在我熟悉的欧洲脚本中)通常包含点,短划线和撇号等字符,这些字符属于“公共”脚本,而不是特定于语言的字体一。考虑到这些因素,上面表达式中“块”的更真实版本可能是这样的:

 ((\p{SomeScript}+(\. ?|[ '-]))*\p{SomeScript}+)

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

一般来说,验证人名是一个复杂的问题,无法100%准确地解决。有关详细信息和示例,请参阅this funny post及其中的注释。