参考:
.Net 源码 手机号码数据注释

/// <summary>
    /// 人名验证属性
    /// </summary>
    public sealed class NameAttribute:ValidationAttribute
    {
        /// <summary>
        /// 正则匹配
        /// </summary>
        private static Regex _regex = CreateRegEx();
        public NameAttribute()
        {
            ErrorMessage = ErrorModel.INVALID_NAME;
        }
        /// <summary>
        /// 判断是否合法
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public override bool IsValid(object value)
        {
            // 如果是空的话自动通过,判断空用 Required 属性
            if (value == null)
            {
                return true;
            }
            return value is string valueAsString && _regex.Match(valueAsString).Length > 0;
        }
        /// <summary>
        /// 创建正则表达式
        /// </summary>
        /// <returns></returns>
        private static Regex CreateRegEx()
        {
            const string pattern = @"^[\u4e00-\u9fa5_a-zA-Z· ]{2,}$";
            const RegexOptions options = RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture;
            // 默认 2S 秒匹配不了即超时
            TimeSpan matchTimeout = TimeSpan.FromSeconds(2);
            try
            {
                if (AppDomain.CurrentDomain.GetData("REGEX_DEFAULT_MATCH_TIMEOUT") == null)
                {
                    return new Regex(pattern, options, matchTimeout);
                }
            }
            catch
            {
            }
            return new Regex(pattern, options);
        }
    }