在正则表达式中接受国际名称字符

10

我一直对正则表达式感到困扰,如果这种方法似乎很糟糕,请原谅我。

当用户输入名字和姓氏时,我开始只使用基本的检查方法,检查大小写、空格、撇号和连字符。

if (!preg_match("/^[a-zA-Z\s'-]+$/", $name)) { // Error }

现在我意识到这不是最好的方法,因为人们可能会有像Dr. Martin Luther King, Jr.(带逗号和句号)这样的东西。因此,我认为将其更改为以下内容会使其稍微更有效。

if (!preg_match("/^[a-zA-Z\s,.'-]+$/", $name)) { // Error }

我在Facebook上看到了一个我认识的女孩的名字,她把自己的名字写作Siân,这让我想到含有umlauts以及日语/中文/韩语/俄语字符的名称。于是我开始搜索,并发现可以像这样通过将每个字符写入其中来实现。

if (!preg_match("/^[a-zA-Z\sàáâäãåèéêëìíîïòóôöõøùúûüÿýñçčšžÀÁÂÄÃÅÈÉÊËÌÍÎÏÒÓÔÖÕØÙÚÛÜŸÝÑßÇŒÆČŠŽ∂ð ,.'-]+$/u", $first_name)) { // Error }

可以想象,这非常冗长,我几乎可以确定有一个更简单的正则表达式可以实现这个功能。就像我说的,我已经搜索过了,但这是我能做到的最好的。

所以,有什么好的方法来检查大写和小写字母、逗号、句号、撇号、连字符、umlauts、拉丁文、日语/俄语等吗?


除非您首先进行规范化,否则那是行不通的,即使这样做有时也不行。 - tchrist
3个回答

32

非常感谢,为什么我之前找不到这个,哈!你能告诉我你所说的缩写类名是什么意思吗? - no.
@HelloJoe:这不是最显而易见的功能。我在 PHP 手册中找到文档时已经很晚了。缩写:PCRE 仅支持 \p{L},而不支持例如 \p{Letter}\p{Russian} - mario
你的文本中有,.',如果它是一个名字的话,你可能想要去掉它。 - matrixdevuk
2
非常完美,谢谢。但是表达式中有一个小错误, 正确的应该是:/^[a-zA-Z\s,.'\-\pL]+$/u 或者 /^[a-z\s,.'-\pL]+$/iu - mrDinkelman
it doesn't cover æøå or ß - TheCrazyProfessor

7

\pL已经包括了a-zA-Z,因此提到的模式"/^[a-zA-Z\s,.'-\pL]+$/u"可以简化为

"/^[\s,.'-\pL]+$/"

同时,修饰符u是不必要的。


4
虽然我最初打算因为提到 a-zA-Z 是多余的而给出加一的意见,但是必须提到 u 修饰符是必需的,否则 PHP 不支持多字节编码。 - dotancohen
我在我的DEV机器上进行了测试,并且它即使没有u修饰符也能正常工作。 - staabm
你是在使用UTF-8或其他多字节编码,还是单字节编码,例如ASCII或latin1?对于单字节编码,u修饰符是不必要的。 - dotancohen

3

可以允许其他类型的标点符号,这样可能会放宽资格限制。

但是有一条限制应该保留,那就是需要至少一个字母。

if (!preg_match("/^[\s,.'-]*\p{L}[\p{L}\s,.'-]*$/u", $name))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接