我正在使用PHP构建一个全球网站,我想让用户能够用自己的语言输入自己的名字,而不仅仅是英语。例如:印度人将能够用印度字母输入自己的姓名,俄罗斯人将能够用俄罗斯字母输入姓名,等等。
现在,我允许名字和姓氏只由字母组成。所以我的问题是我应该如何验证这些名称?我的意思是:我该如何检查那些名字是否只由字母组成?如果我只有英文名字,它会是这样的:preg_match('/[^A-Za-z]/', $fname.$lname)
,但现在我不仅有英文字母。
注意:我没有选择为每种不同的语言及其字母反复编写此验证公式。
感谢您到目前为止阅读此问题。有什么想法吗??
如果要使用regex验证名称,则必须使用/u
修饰符打开Unicode模式。在Unicode模式下,PCRE字符类不仅匹配ASCII字母,还包括任何语言和脚本中的字母字符。假设您使用了[:alpha:]
类或p{L}
,这就是[:alpha:]
类在上使用Unicode扩展到的内容
$fname = 'हिन्दी';
$lname = 'Русский';
preg_match('/[^[:alpha:]]/u', $fname.$lname));
这里";Russkiy";如预期的那样进行验证;印地语";失败。但为什么呢?印地语是一个abugida脚本,例如元音变音符号和固有的元音静音符是其结构的一部分。可以假定上述寄存器中的"ि"
、"्"
和"ी"
为字母;然而他们没有。它们属于不同的类别p{M}
,或与其他字符组合的字符。然后,为了匹配阿布吉达字母语言(例如印度文字,包括缅甸语、泰语、藏语等(,我们应该使用:
preg_match('/([^p{L}p{M}])/u', $fname.$lname));
我已经初步验证了这种组合是匹配字母,并按照以下语言中的预期组合标记字符:阿卡德语、阿拉伯语、亚美尼亚语、希腊语、古吉拉特语、希伯来语、印地语、日语、马拉雅拉姆语、普通话、俄语、僧伽罗语、苏美尔语、泰米尔语。更详尽的测试正在进行中,可以肯定的是,上面的内容将涵盖你的大部分字母基础。
现在,讨论一个与unicode完全无关的验证名称的问题。我注意到你不允许名字中有空格。害怕当"Abraham Van Helsing">和";奥萨马·本·拉登试着注册。然后,你不允许经期。"V.S.Achuthanandan">,人们都叫他"Vee Es";,因为";Velikkakathu Sankaran";让你的嘴疲劳。那么"J.K.罗琳">?
同样,您不允许使用破折号。"卡里姆·阿卜杜勒·贾巴尔">和";Jean-Luc Picard">。没有职业篮球或翘曲驱动器为你。同样,不允许使用撇号意味着"em";阿尔塔南伯爵可能会挑战你进行决斗,而未来现在可能属于天网,因为"Sarah O'Connor">注册失败。她不会回来了。你的网站不是很酷。
好的老鲍比桌呢。Robert'); DROP TABLE students;--
或埃隆·马斯克的新生儿";XÆA-12">。在那里,我告诉过你如何用任何语言匹配任何字母或其片段。我还暗示,如果你允许以上所有内容,基本上是一个避免误报的基线,这可能与一开始就不检查没有太大区别。给予"x!1.യ!!O’/null1 W0W@本@?">如果他们真的想要的话,他/她可以自由使用一个奇怪的名字。
进一步阅读:
- Regex Unicode字符类
- W3C国际化:世界各地的人名