Java 中的电子邮件验证

2025-07-15 20:24:56
3 次阅读
0 个评论

1.简单的正则表达式验证


验证电子邮件地址的最简单的正则表达式是^(.+)@(\S+) $。


它仅检查电子邮件地址中是否存在@符号。如果存在,则验证结果返回true ,否则返回false。但是,此正则表达式不检查电子邮件的本地部分和域。


例如,根据此正则表达式,username@domain.com将通过验证,但username#domain.com将无法通过验证。


让我们定义一个简单的辅助方法来匹配正则表达式模式:



public static boolean patternMatches(String emailAddress, String regexPattern) {
    return Pattern.compile(regexPattern)
      .matcher(emailAddress)
      .matches();
}



我们还将编写代码来使用以下正则表达式验证电子邮件地址:



@Test
public void testUsingSimpleRegex() {
    emailAddress = "username@domain.com";
    regexPattern = "^(.+)@(\\S+)$";
    assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
}


如果电子邮件地址中没有@符号,验证也将失败。



2.严格的正则表达式验证


现在让我们编写一个更严格的正则表达式来检查电子邮件的本地部分以及域部分:

^(?=.{1,64}@)[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*@[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$

使用此正则表达式会对电子邮件地址的本地部分施加以下限制:它允许从 0 到 9 的数值。允许使用从 a 到 z 的大写和小写字母。允许使用下划线“_”、连字符“-”和点“。”本地部分的开始和结束处不允许使用点。不允许使用连续的点。对于本地部分,最多允许 64 个字符。此正则表达式中的域部分的限制包括:它允许从 0 到 9 的数值。我们允许从 a 到 z 的大写和小写字母。域名部分的开始和结束处不允许使用连字符“-”和点“。”。没有连续的点。我们还将编写代码来测试这个正则表达式:




@Test
public void testUsingStrictRegex() {
    emailAddress = "username@domain.com";
    regexPattern = "^(?=.{1,64}@)[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*@" 
        + "[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$";
    assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
}




因此,通过此电子邮件验证技术有效的一些电子邮件地址是:


username@domain.com

user.name@domain.com

user-name@domain.com

username@domain.co.in

user_name@domain.com


以下是一些将通过此电子邮件验证无效的电子邮件地址的简短列表:

username.@domain.com

.user.name@domain.com

user-name@domain.com.

username@.com




3.用于验证非拉丁或 Unicode 字符电子邮件的正则表达式


我们在上一节中看到的正则表达式适用于用英语书写的电子邮件地址,但不适用于非拉丁语电子邮件地址。

因此我们将编写一个正则表达式,以便也可以用来验证 unicode 字符:

^(?=.{1,64}@)[\\p{L}0-9_-]+(\\.[\\p{L}0-9_-]+)*@[^-][\\p{L}0-9-]+(\\.[\\p{L}0-9-]+)*(\\.[\\p{L}]{2,})$

我们可以使用此正则表达式来验证 Unicode 或非拉丁电子邮件地址以支持所有语言。

我们可以看到,这个正则表达式与上一节中构建的严格正则表达式类似,只是我们将“ A-Za-Z ”部分替换成了“ \\p{L} ”。这是为了支持 Unicode 字符。让我们通过编写测试来检查这个正则表达式:

@Test
public void testUsingUnicodeRegex() {
    emailAddress = "用户名@领域.电脑";
    regexPattern = "^(?=.{1,64}@)[\\p{L}0-9_-]+(\\.[\\p{L}0-9_-]+)*@" 
        + "[^-][\\p{L}0-9-]+(\\.[\\p{L}0-9-]+)*(\\.[\\p{L}]{2,})$";
    assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
}

该正则表达式不仅提供了一种更严格的方法来验证电子邮件地址,而且还支持非拉丁字符。


4. RFC 5322 的正则表达式用于电子邮件验证


我们可以使用 RFC 标准提供的正则表达式来验证电子邮件地址,而不必编写自定义正则表达式。

RFC 5322是RFC 822的更新版本,它提供了用于电子邮件验证的正则表达式。

让我们检查一下:

^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$

我们可以看到,这是一个非常简单的正则表达式,允许电子邮件中的所有字符。

但是,它不允许使用管道字符 (|) 和单引号 ('),因为这些字符从客户端传递到服务器时存在潜在的SQL 注入风险。让我们编写代码来使用此正则表达式验证电子邮件:

@Test
public void testUsingRFC5322Regex() {
    emailAddress = "username@domain.com";
    regexPattern = "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$";
    assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
}


5.使用正则表达式检查顶级域名中的字符


我们已经编写了正则表达式来验证电子邮件地址的本地部分和域部分。现在,我们还将编写一个正则表达式来检查电子邮件的顶级域名。

以下正则表达式验证电子邮件地址的顶级域部分:

^[\\w!#$%&'*+/=?`{|}~^-]+(?:\\.[\\w!#$%&'*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$

这个正则表达式基本上检查电子邮件地址是否只有一个点,以及顶级域名中至少有两个字符,最多有六个字符。

我们还将编写一些代码来使用此正则表达式验证电子邮件地址:

@Test
public void testTopLevelDomain() {
    emailAddress = "username@domain.com";
    regexPattern = "^[\\w!#$%&'*+/=?`{|}~^-]+(?:\\.[\\w!#$%&'*+/=?`{|}~^-]+)*" 
        + "@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$";
    assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
}


6.正则表达式限制连续点、尾随点和前导点


现在让我们编写一个正则表达式来限制电子邮件地址中点的使用:

^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\\.[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+)*@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$上述正则表达式用于限制连续的点号、前导点号和尾随点号。因此,一封电子邮件可以包含多个点号,但在本地和域部分中不能包含连续的点号。

我们来看看代码:

@Test
public void testRestrictDots() {
    emailAddress = "username@domain.com";
    regexPattern = "^[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\\.[a-zA-Z0-9_!#$%&'*+/=?`{|}~^-]+)*@" 
        + "[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$";
    assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
}


7.OWASP验证正则表达式此正则表达式

由OWASP 验证正则表达式存储库提供,用于检查电子邮件验证:

^[a-zA-Z0-9_+&*-] + (?:\\.[a-zA-Z0-9_+&*-] + )*@(?:[a-zA-Z0-9-]+\\.) + [a-zA-Z]{2, 7}

该正则表达式还支持标准电子邮件结构中的大多数验证。

让我们使用以下代码验证电子邮件地址:

@Test
public void testOwaspValidation() {
    emailAddress = "username@domain.com";
    regexPattern = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
    assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
}

8.Gmail 电子邮件特例


有一个特殊情况仅适用于 Gmail 域名:允许在电子邮件的本地部分使用字符 + 字符。对于 Gmail 域名,username+something@gmail.com和username@gmail.com这两个电子邮件地址是相同的。

此外,username@gmail.com与user+name@gmail.com类似。我们必须实现一个稍微不同的正则表达式,以便也能通过这种特殊情况下的电子邮件验证:

^(?=.{1,64}@)[A-Za-z0-9_-+]+(\\.[A-Za-z0-9_-+]+)*@[^-][A-Za-z0-9-+]+(\\.[A-Za-z0-9-+]+)*(\\.[A-Za-z]{2,})$

让我们写一个例子来测试这个用例:

@Test
public void testGmailSpecialCase() {
    emailAddress = "username+something@domain.com";
    regexPattern = "^(?=.{1,64}@)[A-Za-z0-9\\+_-]+(\\.[A-Za-z0-9\\+_-]+)*@" 
        + "[^-][A-Za-z0-9\\+-]+(\\.[A-Za-z0-9\\+-]+)*(\\.[A-Za-z]{2,})$";
    assertTrue(EmailValidation.patternMatches(emailAddress, regexPattern));
}

9.Apache Commons 电子邮件验证器

Apache Commons Validator是一个包含标准验证规则的验证包。通过导入此包,我们就可以应用电子邮件验证。

我们可以使用EmailValidator类来验证电子邮件,该类遵循 RFC 822 标准。此验证器包含自定义代码和正则表达式,用于验证电子邮件。它不仅支持特殊字符,还支持我们讨论过的 Unicode 字符。

让我们在项目中添加commons-validator依赖项:

<dependency>
    <groupId>commons-validator</groupId>
    <artifactId>commons-validator</artifactId>
    <version>1.8</version>
</dependency>

现在我们可以使用以下代码验证电子邮件地址:

@Test
public void testUsingEmailValidator() {
    emailAddress = "username@domain.com";
    assertTrue(EmailValidator.getInstance()
      .isValid(emailAddress));
}


我应该使用哪个正则表达式?在本文中,我们研究了使用正则表达式进行电子邮件地址验证的各种解决方案。显然,确定我们应该使用哪种解决方案取决于我们希望验证的严格程度以及我们的具体需求。

例如,如果我们只需要一个简单的正则表达式来检查电子邮件中是否存在@符号,那么可以使用第 1 节中的简单正则表达式。但是,如果需要更详细的验证,我们可以选择第 4 节中基于 RFC5322 标准的更严格的正则表达式解决方案。

最后,如果我们处理电子邮件中的 Unicode 字符,我们可以采用第 3 节中提供的正则表达式解决方案。




登录后回答。没有帐号?注册一个。