一尘不染

用于验证姓名的正则表达式?

c#

尽管这似乎是一个琐碎的问题,但我很确定这不是一个小问题:)

我需要验证来自世界各地的人的名字和姓氏。想象一下一个巨大的名字和姓氏的缩略语列表,在这里我需要尽可能地删除我发现的所有碎片。我该如何使用正则表达式呢?如果只是英语,那我想这会减少它:

^[a-z -']+$

但是,我还需要支持以下情况:

  • 其他标点符号,因为它们可能会在不同的国家/地区使用(不知道使用哪个标点符号,但也许可以!)
  • 不同的Unicode字母集(重音字母,希腊语,日语,中文等)
  • 没有数字或符号或不必要的标点符号或符文等。
  • 标题,中间名首字母,后缀不是此数据的一部分
  • 名称已经由姓氏分隔。
  • 我们已准备好将超级稀有名称简化(存在一个名为“ @”的人,但在每个地方都不允许使用该字符是没有意义的。请务实且明智。)
  • 请注意,许多国家/地区都有关于名称的法律,因此需要遵循一些标准

我可以执行一些标准方法来验证这些字段,以确保我们的网站用户拥有丰富的经验,并且可以在列表中注册时实际 使用其名称 吗?

我会寻找与您可以在Google上找到的许多“电子邮件地址”正则表达式类似的东西。


阅读 1304

收藏
2020-05-19

共1个答案

一尘不染

我会尝试自己给出一个正确的答案:

名称中唯一应允许的标点是句号,撇号和连字符。在角落案例列表中,我还没有看到其他案例。

关于数字,只有一个8的情况。我想我可以放心地拒绝。

关于字母,任何字母都是有效的。

我也想包括空间。

这将总结为这个正则表达式:

^[\p{L} \.'\-]+$

这提出了一个问题,即撇号可以用作攻击媒介。它应该被编码。

因此,验证代码应如下所示(未经测试):

var name = nameParam.Trim();
if (!Regex.IsMatch(name, "^[\p{L} \.\-]+$")) 
    throw new ArgumentException("nameParam");
name = name.Replace("'", "'");  //' does not work in IE

谁能想到一个名称不能通过该测试或可能通过的XSS或SQL注入的原因?


完整的测试解决方案

using System;
using System.Text.RegularExpressions;

namespace test
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            var names = new string[]{"Hello World", 
                "John",
                "João",
                "タロウ",
                "やまだ",
                "山田",
                "先生",
                "мыхаыл",
                "Θεοκλεια",
                "आकाङ्क्षा",
                "علاء الدين",
                "אַבְרָהָם",
                "മലയാളം",
                "상",
                "D'Addario",
                "John-Doe",
                "P.A.M.",
                "' --",
                "<xss>",
                "\""
            };
            foreach (var nameParam in names)
            {
                Console.Write(nameParam+" ");
                var name = nameParam.Trim();
                if (!Regex.IsMatch(name, @"^[\p{L}\p{M}' \.\-]+$"))
                {
                    Console.WriteLine("fail");
                    continue;
                }
                name = name.Replace("'", "&#39;");
                Console.WriteLine(name);
            }
        }
    }
}
2020-05-19