ASP.NET Core [RegularExpression] 验证失败,即使正则表达式明显正确

ASP.NET Core [RegularExpression] validation fails, even though the regex is demonstrably correct

提问人:EJoshuaS - Stand with Ukraine 提问时间:7/29/2023 更新时间:7/29/2023 访问量:69

问:

我有以下方法:

public async Task<IActionResult> GetUsersAPICall([Bind(nameof(query))] [RegularExpression(@"^\w+(\.\w+)*@\w+(\.\w+)+|(\w+(\s\w+)*)|[a-z0-9]+$", ErrorMessage = "This does not look like a valid query")] string query)
{
    if (!ModelState.IsValid)
    {
       return BadRequest();
    }
}

对于以下电子邮件地址,此操作会失败(但对于此类电子邮件地址,则不会失败)。[email protected][email protected]

我知道正则表达式是正确的模式,因为以下 LINQPad 脚本按预期显示完全相同的电子邮件地址:True

void Main()
{
    var r = new Regex(@"^\w+(\.\w+)*@\w+(\.\w+)+|(\w+(\s\w+)*)|[a-z0-9]+$");
    
    r.IsMatch("[email protected]").Dump();
}

我试着完全放弃,但这没有帮助。[Bind(nameof(query))]

如果我将其更改为

public async Task<IActionResult> GetUsersAPICall([Bind(nameof(query))] string query)
{
    if (!Regex.IsMatch(query, @"^\w+(\.\w+)*@\w+(\.\w+)+|(\w+(\s\w+)*)|[a-z0-9]+$"))
    {
        return BadRequest();
    }

    // ...
}

我完全不明白为什么我最初的东西不起作用。有人能看到我在这里错过了什么吗?

到目前为止,我在 Stack Overflow 上找到的最接近的是这个问答,但事实证明 OP 的正则表达式是错误的(对我来说并非如此,因为正则表达式在两个不同的上下文中工作得很好)。

C# asp.net 正则表达式 ASP.NET 核心 验证

评论

2赞 InSync 7/29/2023
"我知道正则表达式是正确的模式“:我不认为这是你预期的结果......
0赞 EJoshuaS - Stand with Ukraine 7/29/2023
@InSync我很困惑,那么 - 相同的模式似乎在 LINQPad 中起作用。我错过了什么愚蠢的东西吗?
2赞 InSync 7/29/2023
我不知道 ASP.NET/C#,所以我不确定你想匹配什么。如果您要查找的是电子邮件地址,请参阅此问题。主要问题是正则表达式中的管道 () 正在分割表达式,因此仅适用于第一部分和最后一部分。也许您的意思是将这些部分包含在一组()中?|^$^(...|...|...)$

答:

1赞 markalex 7/29/2023 #1

问题出在您的正则表达式中,并且其处理方式和注释的差异。IsMatchRegularExpression

IsMatch检查输入是否包含与提供的正则表达式匹配的任何内容。文档

指示指定的正则表达式是否使用指定的匹配选项和超时间隔在指定的输入字符串中查找匹配项。

因此,它试图在您的输入中找到任何匹配项,找到它(特别是用于第二次更改:)并返回 true。(\w+(\s\w+)*)

RegularExpression另一方面,注释会检查您的整个输入是否与提供的正则表达式匹配。文档

正则表达式搜索完全匹配,不在模式之前和模式结束时使用会产生与使用它相同的结果。对于搜索匹配,请在模式前面加上 .^$.*

因此,有效地,注释应用了模式。^(?:^\w+(\.\w+)*@\w+(\.\w+)+|(\w+(\s\w+)*)|[a-z0-9]+$)$

可能您试图达到类似的效果,但忘记了括号?

评论

0赞 EJoshuaS - Stand with Ukraine 7/29/2023
好点子,谢谢。我真的很困惑。