【问题标题】:Email Validation: converting a regular expression written in PHP (preg) to .NET (Regex)电子邮件验证:将用 PHP (preg) 编写的正则表达式转换为 .NET (Regex)
【发布时间】:2011-01-03 09:28:21
【问题描述】:

根据这个答案... Using a regular expression to validate an email address

这让我来到了这个网站... http://fightingforalostcause.net/misc/2006/compare-email-regex.php

我想使用这个正则表达式来验证我的 ASP.NET MVC 应用程序的电子邮件:

/^[-_a-z0-9\'+*$^&%=~!?{}]++(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*+@(?:(?![-.])[-a-z0-9.]+(?<![-.])\.[a-z]{2,6}|\d{1,3}(?:\.\d{1,3}){3})(?::\d++)?$/iD

很遗憾,我收到了这个错误

System.ArgumentException 未被用户代码处理 Message="解析\"/^[-_a-z0-9\'+$^&%=~!?{}]++(?:\.[-_a-z0-9\'+$^&%=~!?{}]+)*+@(?:(?![-.])[-a-z0-9.]+(?

有没有人将其转换为可供 .NET 的 Regex 类使用,或者是否有另一个更适合 PHP 的 preg_match 函数的 .NET 正则表达式类?

【问题讨论】:

  • 请发布您的代码。我预见到转义字符问题。

标签: c# .net php asp.net regex


【解决方案1】:

.NET 中的正则表达式的问题在于不支持所有格量​​词。如果您删除它们,它会起作用。这是作为 C# 字符串的正则表达式:

@"^[-_a-z0-9\'+*$^&%=~!?{}]+(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*@(?:(?![-.])[-a-z0-9.]+(?<![-.])\.[a-z]{2,6}|\d{1,3}(?:\.\d{1,3}){3})(?::\d+)?$"

这是一个基于 the page you linked to 的测试平台,包括所有应该匹配的字符串和前三个不应该匹配的字符串:

using System;
using System.Text.RegularExpressions;

public class Program
{
    static void Main(string[] args)
    {
        foreach (string email in new string[]{
            "l3tt3rsAndNumb3rs@domain.com",
            "has-dash@domain.com",
            "hasApostrophe.o'leary@domain.org",
            "uncommonTLD@domain.museum",
            "uncommonTLD@domain.travel",
            "uncommonTLD@domain.mobi",
            "countryCodeTLD@domain.uk",
            "countryCodeTLD@domain.rw",
            "lettersInDomain@911.com",
            "underscore_inLocal@domain.net",
            "IPInsteadOfDomain@127.0.0.1",
            "IPAndPort@127.0.0.1:25",
            "subdomain@sub.domain.com",
            "local@dash-inDomain.com",
            "dot.inLocal@foo.com",
            "a@singleLetterLocal.org",
            "singleLetterDomain@x.org",
            "&*=?^+{}'~@validCharsInLocal.net",
            "missingDomain@.com",
            "@missingLocal.org",
            "missingatSign.net"
        })
        {
            string s = @"^[-_a-z0-9\'+*$^&%=~!?{}]+(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*@(?:(?![-.])[-a-z0-9.]+(?<![-.])\.[a-z]{2,6}|\d{1,3}(?:\.\d{1,3}){3})(?::\d+)?$";
            bool isMatch = Regex.IsMatch(email, s, RegexOptions.IgnoreCase);
            Console.WriteLine(isMatch);
        }
    }
}

输出:

True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
True
False
False
False

一个问题是它无法匹配一些有效的电子邮件地址,例如foo\@bar@example.com。配得太多总比配得少好。

【讨论】:

  • 感谢您的尝试,但这会拒绝除此站点上的两个有效电子邮件之外的所有电子邮件:fightingforalostcause.net/misc/2006/compare-email-regex.php,因此转换不等效。
  • 你记得使用不区分大小写的匹配吗?这些电子邮件中只有两封只有小写字母,我猜那是您成功匹配的两封。我添加了一些代码来展示如何将正则表达式与 IgnoreCase 选项一起使用。
  • 对于RegexOptions.IgnoreCase,它只接受 has-dash@domain.com 和 subdomain@sub.domain.com。所有其他有效的电子邮件都被拒绝。
  • 我自己查过了。它适用于所有给定的电子邮件!您的代码中一定有错误。我会提供更多的源代码。
  • @Mark,我很抱歉。今天早上刚检查了我的代码,我将IgnoreCase 放在了我的代码的一部分中,但没有放在另一部分中。修复此问题后,结果看起来好多更好。它接受所有有效的电子邮件,它接受的唯一无效电子邮件是 TLDDoesntExist@domain.moc 和 local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org。
【解决方案2】:

您真的不应该使用 RegEx 来解析 .NET 中的电子邮件地址。更好的选择是使用框架中内置的功能。

尝试在MailAddress 类的构造函数中使用您的电子邮件字符串。如果它抛出 FormatException 则地址不好。

try 
{
    MailAddress addr = new MailAddress("theEmail@stackoverflow.com")
    // <- Valid email if this line is reached
}
catch (FormatException)
{
    // <- Invalid email if this line is reached
}

您可以看到answer a Microsoft developer gave to another email validation question,他在其中解释了 .NET 的电子邮件解析如何在 .NET 4.0 中得到显着改进。由于在回答这个问题时,.NET 4.0 仍处于测试阶段,您可能没有运行它,但即使是以前版本的框架也有足够的电子邮件地址解析代码。请记住,最终您很可能会使用MailAddress 类来发送您的电子邮件。为什么不使用 it 来验证您的电子邮件地址。最后,对MailAddress 类有效才是最重要的。

【讨论】:

  • 在 .NET 3.5 上测试,它接受不少无效的电子邮件地址:missingDomain@.com、missingDot@com、someone-else@127.0.0.1.26、domainStartsWithDash@-domain.com、domainEndsWithDash @domain-.com、TLDDoesntExist@domain.moc、numbersInTLD@domain.c0m 和 local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org。也就是说,无论如何使用MailAddress 发送电子邮件,您都提出了一个很好的观点。也许 .NET 4.0 做得更好。
  • @DanThMan 这些地址不一定无效。您提到的大多数地址都可能在内部网络上,因此可能是有效的。请记住,允许无效地址比拒绝有效地址要好。
  • @Dan,另一个好点,但对于这个特定的应用程序,我肯定期待 Internet 电子邮件地址(而不是 Intranet)。不过,目前我认为我最喜欢这个解决方案。我实际上需要发送电子邮件,因此使用MainAddress 进行验证似乎是可行的方法。
  • 我同意 DH 的观点,即避免使用 RegEx 进行电子邮件地址验证。让 .NET Framework 进行此验证;这样做可以减少编码工作并产生更优雅的电子邮件验证解决方案。
【解决方案3】:

我之前在一堆电子商务应用程序中使用过这个功能,从来没有遇到过问题。

    public static bool IsEmailValid(string emailAddress)
    {
        Regex emailRegEx = new Regex(@"\b[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b");
        if (emailRegEx.IsMatch(emailAddress))
        {
            return true;
        }

        return false;
    }

【讨论】:

    【解决方案4】:

    .NET 正则表达式语法与 PHP 中的不一样,Regex 是唯一使用正则表达式的内置类(但可能还有其他第三方实现)。无论如何,使用Regex 验证电子邮件地址非常容易...直接from the source

    ^([0-9a-zA-Z]([-\.\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    • 2011-10-27
    相关资源
    最近更新 更多