瑞典 SSN 正则表达式拒绝特定年龄以下的用户
Swedish SSN Regular expression reject users under a specific age
我的正则表达式有问题。我已经可以验证正确的瑞典社会安全号码以符合这些标准。
- YYMMDDNNNN
- YYMMDD-NNNN
- YYYYMMDDNNNN
- YYYYMMDD-NNNN
但如果用户未满 18 岁,我也想拒绝用户注册。我的正则表达式现在看起来像这样:有没有人遇到过年龄范围瑞典 SSN 的相同问题?
private const string RegExForValidation =
@"^(\d{6}|\d{8})[-|(\s)]{0,1}\d{4}$";
更新
private const string RegExForValidation = @"^(?<date>\d{6}|\d{8})[-\s]?\d{4}$";
string date = Regex.Match("19970918-1234", RegExForValidation).Groups["date"].Value;
DateTime dt;
[Required(ErrorMessage = "Du måste ange personnummer")]
[RegularExpression(RegExForValidation, ErrorMessage = "Personnummer anges med 10 siffror (yymmddnnnn)")]
public string PersonalIdentityNumber { get; set; }
第二次更新
public class ValidateOfAge : ValidationAttribute
{
public bool IsOfAge(DateTime birthdate)
{
DateTime today = DateTime.Today;
int age = today.Year - 18;
if (birthdate.AddYears(birthdate.Year) < today.AddYears(-age))
return false;
else
return true;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string RegExForValidation = @"^(?<date>\d{6}|\d{8})[-\s]?\d{4}$";
string date = Regex.Match((string)value, RegExForValidation).Groups["date"].Value;
DateTime dt;
if (DateTime.TryParseExact(date, new[] { "yyMMdd", "yyyyMMdd" }, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
if (IsOfAge(dt))
return ValidationResult.Success;
return new ValidationResult("Personnummer anges med 10 siffror (yymmddnnnn)");
}
}
您需要从 SSN 中获取出生日期,解析为 DateTime,然后与今天的日期进行比较。
检查一个人是否已成年的方法如下:
public bool IsOfAge(DateTime birthdate)
{
DateTime today = DateTime.Today; // Calculating age...
int age = today.Year - birthdate.Year;
if (birthdate > today.AddYears(-age))
age--;
return age < 18 ? false : true; // If the age is 18+ > true, else false.
}
这里是你如何使用它:
string RegExForValidation = @"^(?<date>\d{6}|\d{8})[-\s]?\d{4}$";
string date = Regex.Match("19970918-1234", RegExForValidation).Groups["date"].Value;
DateTime dt;
if (DateTime.TryParseExact(date, new[] { "yyMMdd", "yyyyMMdd" }, new CultureInfo("sv-SE"), DateTimeStyles.None, out dt))
Console.WriteLine(IsOfAge(dt));
请注意 [-|(\s)]
匹配 -
、|
、(
、空格或 )
。我确定您只想匹配连字符或空格。
我在正则表达式中添加了命名捕获并从字符 class 中删除了不必要的符号。另外,请注意 {0,1}
与 ?
.
相同
更新
要使其在 MVC 应用程序中运行,您需要实施自定义验证器:
[Required(ErrorMessage = "Du måste ange personnummer")]
[ValidateOfAge] // <---------------------------- HERE
public string PersonalIdentityNumber { get; set; }
并按如下方式实现:
public class ValidateOfAge: ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string RegExForValidation = @"^(?<date>\d{6}|\d{8})[-\s]?\d{4}$";
string date = Regex.Match((string)value, RegExForValidation).Groups["date"].Value;
DateTime dt;
if (DateTime.TryParseExact(date, new[] { "yyMMdd", "yyyyMMdd" }, new CultureInfo("sv-SE"), DateTimeStyles.None, out dt))
if (IsOfAge(dt))
return ValidationResult.Success;
return new ValidationResult("Personnummer anges med 10 siffror (yymmddnnnn)");
}
}
在这种情况下,我不会使用正则表达式,而是依赖基础 class 库的内置 DateTime 解析功能:
public DateTime GetBirthDate(string ssn)
{
var strippedOfSerial =
ssn.Substring(0, ssn.Length - 4).TrimEnd('-');
return DateTime.ParseExact(
strippedOfSerial,
new[] { "yyMMdd", "yyyyMMdd" },
new CultureInfo("se-SE"),
DateTimeStyles.None);
}
现在您可以查看返回的 DateTime
值并将其与 DateTime.Now
进行比较以确定是否要拒绝它。
在我看来,这比依赖正则表达式更具可读性,而且可能更安全、更灵活。如您所知,您可以例如使用其他文化等来调整解析策略。
我建议不要使用自定义 RegEx,而是查看可用的 NuGet 包,它能够解析有效的瑞典个人身份证号码,然后提取可用作输入的信息,例如出生日期、年龄、性别等你的验证。 .GetAge()
方法与您的情况最相关。 免责声明:我是该软件包的合著者之一。
使用 SwedishPersonalIdentityNumber
的 ValidateOfAge
的实现可能如下所示:
public class ValidateOfAge : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (SwedishPersonalIdentityNumber.TryParse((string)value, out var personalIdentityNumber))
{
if(personalIdentityNumber.GetAge() >= 18) {
return ValidationResult.Success;
} else {
return new ValidationResult("Du måste vara minst 18 år gammal.");
}
}
return new ValidationResult("Ogiltigt personnummer.");
}
}
SwedishPersonalIdentityNumber
支持您描述的模式,包括更多有效模式(例如,您知道 PIN 可以包含 + 吗?)。
- 您可以在这里找到源代码:
- 这里是 NuGet 上的包:
第二个包含验证属性,用于验证模型中的 PIN。
如果验证年龄的用例足够普遍,我们可以将其实现到该验证属性中。我created an issue了解一下兴趣和设计。
目前提出的API设计是这样的(针对你的场景):
[SwedishPersonalIdentityNumber(MinimumAge = 18)]
public string PersonalIdentityNumber { get; set; }
如果您希望看到实施,请在问题中分享您的想法。
我的正则表达式有问题。我已经可以验证正确的瑞典社会安全号码以符合这些标准。
- YYMMDDNNNN
- YYMMDD-NNNN
- YYYYMMDDNNNN
- YYYYMMDD-NNNN
但如果用户未满 18 岁,我也想拒绝用户注册。我的正则表达式现在看起来像这样:有没有人遇到过年龄范围瑞典 SSN 的相同问题?
private const string RegExForValidation =
@"^(\d{6}|\d{8})[-|(\s)]{0,1}\d{4}$";
更新
private const string RegExForValidation = @"^(?<date>\d{6}|\d{8})[-\s]?\d{4}$";
string date = Regex.Match("19970918-1234", RegExForValidation).Groups["date"].Value;
DateTime dt;
[Required(ErrorMessage = "Du måste ange personnummer")]
[RegularExpression(RegExForValidation, ErrorMessage = "Personnummer anges med 10 siffror (yymmddnnnn)")]
public string PersonalIdentityNumber { get; set; }
第二次更新
public class ValidateOfAge : ValidationAttribute
{
public bool IsOfAge(DateTime birthdate)
{
DateTime today = DateTime.Today;
int age = today.Year - 18;
if (birthdate.AddYears(birthdate.Year) < today.AddYears(-age))
return false;
else
return true;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string RegExForValidation = @"^(?<date>\d{6}|\d{8})[-\s]?\d{4}$";
string date = Regex.Match((string)value, RegExForValidation).Groups["date"].Value;
DateTime dt;
if (DateTime.TryParseExact(date, new[] { "yyMMdd", "yyyyMMdd" }, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
if (IsOfAge(dt))
return ValidationResult.Success;
return new ValidationResult("Personnummer anges med 10 siffror (yymmddnnnn)");
}
}
您需要从 SSN 中获取出生日期,解析为 DateTime,然后与今天的日期进行比较。
检查一个人是否已成年的方法如下:
public bool IsOfAge(DateTime birthdate)
{
DateTime today = DateTime.Today; // Calculating age...
int age = today.Year - birthdate.Year;
if (birthdate > today.AddYears(-age))
age--;
return age < 18 ? false : true; // If the age is 18+ > true, else false.
}
这里是你如何使用它:
string RegExForValidation = @"^(?<date>\d{6}|\d{8})[-\s]?\d{4}$";
string date = Regex.Match("19970918-1234", RegExForValidation).Groups["date"].Value;
DateTime dt;
if (DateTime.TryParseExact(date, new[] { "yyMMdd", "yyyyMMdd" }, new CultureInfo("sv-SE"), DateTimeStyles.None, out dt))
Console.WriteLine(IsOfAge(dt));
请注意 [-|(\s)]
匹配 -
、|
、(
、空格或 )
。我确定您只想匹配连字符或空格。
我在正则表达式中添加了命名捕获并从字符 class 中删除了不必要的符号。另外,请注意 {0,1}
与 ?
.
更新
要使其在 MVC 应用程序中运行,您需要实施自定义验证器:
[Required(ErrorMessage = "Du måste ange personnummer")]
[ValidateOfAge] // <---------------------------- HERE
public string PersonalIdentityNumber { get; set; }
并按如下方式实现:
public class ValidateOfAge: ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string RegExForValidation = @"^(?<date>\d{6}|\d{8})[-\s]?\d{4}$";
string date = Regex.Match((string)value, RegExForValidation).Groups["date"].Value;
DateTime dt;
if (DateTime.TryParseExact(date, new[] { "yyMMdd", "yyyyMMdd" }, new CultureInfo("sv-SE"), DateTimeStyles.None, out dt))
if (IsOfAge(dt))
return ValidationResult.Success;
return new ValidationResult("Personnummer anges med 10 siffror (yymmddnnnn)");
}
}
在这种情况下,我不会使用正则表达式,而是依赖基础 class 库的内置 DateTime 解析功能:
public DateTime GetBirthDate(string ssn)
{
var strippedOfSerial =
ssn.Substring(0, ssn.Length - 4).TrimEnd('-');
return DateTime.ParseExact(
strippedOfSerial,
new[] { "yyMMdd", "yyyyMMdd" },
new CultureInfo("se-SE"),
DateTimeStyles.None);
}
现在您可以查看返回的 DateTime
值并将其与 DateTime.Now
进行比较以确定是否要拒绝它。
在我看来,这比依赖正则表达式更具可读性,而且可能更安全、更灵活。如您所知,您可以例如使用其他文化等来调整解析策略。
我建议不要使用自定义 RegEx,而是查看可用的 NuGet 包,它能够解析有效的瑞典个人身份证号码,然后提取可用作输入的信息,例如出生日期、年龄、性别等你的验证。 .GetAge()
方法与您的情况最相关。 免责声明:我是该软件包的合著者之一。
使用 SwedishPersonalIdentityNumber
的 ValidateOfAge
的实现可能如下所示:
public class ValidateOfAge : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (SwedishPersonalIdentityNumber.TryParse((string)value, out var personalIdentityNumber))
{
if(personalIdentityNumber.GetAge() >= 18) {
return ValidationResult.Success;
} else {
return new ValidationResult("Du måste vara minst 18 år gammal.");
}
}
return new ValidationResult("Ogiltigt personnummer.");
}
}
SwedishPersonalIdentityNumber
支持您描述的模式,包括更多有效模式(例如,您知道 PIN 可以包含 + 吗?)。
- 您可以在这里找到源代码:
- 这里是 NuGet 上的包:
第二个包含验证属性,用于验证模型中的 PIN。 如果验证年龄的用例足够普遍,我们可以将其实现到该验证属性中。我created an issue了解一下兴趣和设计。
目前提出的API设计是这样的(针对你的场景):
[SwedishPersonalIdentityNumber(MinimumAge = 18)]
public string PersonalIdentityNumber { get; set; }
如果您希望看到实施,请在问题中分享您的想法。