验证字符串是否是有效的电子邮件地址的最优雅的代码是什么?
当前回答
一个简单的没有使用Regex(我不喜欢它的可读性差):
bool IsValidEmail(string email)
{
string emailTrimed = email.Trim();
if (!string.IsNullOrEmpty(emailTrimed))
{
bool hasWhitespace = emailTrimed.Contains(" ");
int indexOfAtSign = emailTrimed.LastIndexOf('@');
if (indexOfAtSign > 0 && !hasWhitespace)
{
string afterAtSign = emailTrimed.Substring(indexOfAtSign + 1);
int indexOfDotAfterAtSign = afterAtSign.LastIndexOf('.');
if (indexOfDotAfterAtSign > 0 && afterAtSign.Substring(indexOfDotAfterAtSign).Length > 1)
return true;
}
}
return false;
}
例子:
IsValidEmail(“@b.com”) // false IsValidEmail(“a@.com”) // false IsValidEmail(“a@bcom”) // false IsValidEmail(“a.b@com”) // false IsValidEmail(“a@b.”) // false IsValidEmail(“a b@c.com”) // false IsValidEmail(“a@b c.com”) // false IsValidEmail(“a@b.com”) // true IsValidEmail(“a@b.c.com”) // true IsValidEmail(“a+b@c.com”) // true IsValidEmail(“a@123.45.67.89”) // true
它意味着简单,因此它不处理罕见的情况,如电子邮件的括号域包含空格(通常是允许的),电子邮件的IPv6地址等。
其他回答
我只是想指出,最近在. net文档中增加了关于电子邮件验证的内容,也使用了Regex操作。 关于它们实现的详细解释可以在那里找到。
https://learn.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format
为了方便起见,下面是他们的测试结果:
// Valid: david.jones@proseware.com
// Valid: d.j@server1.proseware.com
// Valid: jones@ms1.proseware.com
// Invalid: j.@server1.proseware.com
// Valid: j@proseware.com9
// Valid: js#internal@proseware.com
// Valid: j_9@[129.126.118.1]
// Invalid: j..s@proseware.com
// Invalid: js*@proseware.com
// Invalid: js@proseware..com
// Valid: js@proseware.com9
// Valid: j.s@server1.proseware.com
// Valid: "j\"s\""@proseware.com
// Valid: js@contoso.中国
通过system . text . regulareexpressions检查电子邮件字符串的格式是否正确:
public static bool IsValidEmailId(string InputEmail)
{
Regex regex = new Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
Match match = regex.Match(InputEmail);
if (match.Success)
return true;
else
return false;
}
protected void Email_TextChanged(object sender, EventArgs e)
{
String UserEmail = Email.Text;
if (IsValidEmailId(UserEmail))
{
Label4.Text = "This email is correct formate";
}
else
{
Label4.Text = "This email isn't correct formate";
}
}
我认为最好的方法如下:
public static bool EmailIsValid(string email)
{
string expression = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
if (Regex.IsMatch(email, expression))
{
if (Regex.Replace(email, expression, string.Empty).Length == 0)
{
return true;
}
}
return false;
}
你可以在一个通用类中使用这个静态函数。
这是你问题的答案,供你核对。
using System;
using System.Globalization;
using System.Text.RegularExpressions;
public class RegexUtilities
{
public bool IsValidEmail(string strIn)
{
if (String.IsNullOrEmpty(strIn))
{
return false;
}
// Use IdnMapping class to convert Unicode domain names.
try
{
strIn = Regex.Replace(strIn, @"(@)(.+)$", this.DomainMapper, RegexOptions.None, TimeSpan.FromMilliseconds(200));
}
catch (RegexMatchTimeoutException)
{
return false;
}
if (invalid)
{
return false;
}
// Return true if strIn is in valid e-mail format.
try
{
return Regex.IsMatch(strIn, @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))| [-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
}
catch (RegexMatchTimeoutException)
{
return false;
}
}
private string DomainMapper(Match match)
{
// IdnMapping class with default property values.
IdnMapping idn = new IdnMapping();
string domainName = match.Groups[2].Value;
try
{
domainName = idn.GetAscii(domainName);
}
catch (ArgumentException)
{
invalid = true;
}
return match.Groups[1].Value + domainName;
}
}
There are a lot of strong answers here. However, I recommend that we take a step back. @Cogwheel answers the question https://stackoverflow.com/a/1374644/388267. Nevertheless, it could be costly in a bulk validation scenario, if many of the email address being validated are invalid. I suggest that we employ a bit of logic before we enter into his try-catch block. I know that the following code could be written using RegEx but that could be costly for new developers to understand. This is my twopence worth:
public static bool IsEmail(this string input)
{
if (string.IsNullOrWhiteSpace(input)) return false;
// MUST CONTAIN ONE AND ONLY ONE @
var atCount = input.Count(c => c == '@');
if (atCount != 1) return false;
// MUST CONTAIN PERIOD
if (!input.Contains(".")) return false;
// @ MUST OCCUR BEFORE LAST PERIOD
var indexOfAt = input.IndexOf("@", StringComparison.Ordinal);
var lastIndexOfPeriod = input.LastIndexOf(".", StringComparison.Ordinal);
var atBeforeLastPeriod = lastIndexOfPeriod > indexOfAt;
if (!atBeforeLastPeriod) return false;
// CODE FROM COGWHEEL'S ANSWER: https://stackoverflow.com/a/1374644/388267
try
{
var addr = new System.Net.Mail.MailAddress(input);
return addr.Address == input;
}
catch
{
return false;
}
}
推荐文章
- 在没有事件源注册的情况下写入Windows应用程序事件日志
- 并发HashSet<T>在。net框架?
- 从控制器内获得控制器和动作名称?
- 新建T()
- 如何将枚举绑定到WPF中的组合框控件?
- 拒绝访问该路径
- Visual Studio - Resx文件默认“内部”为“公共”
- 使用linq转换列表到字典,不用担心重复
- 单元测试:日期时间。现在
- 什么是回调?
- 返回匿名类型的结果?
- 何时使用IList,何时使用List
- ConfigurationManager。AppSettings在.NET Core 2.0中可用?
- 在c#的控制台应用程序中使用'async
- 在单元测试中设置HttpContext.Current.Session