不使用正则表达式的 Java 电子邮件验证

Posted

技术标签:

【中文标题】不使用正则表达式的 Java 电子邮件验证【英文标题】:Email validation in Java without using regular expression 【发布时间】:2015-08-05 14:12:17 【问题描述】:

我了解使用 Regex 验证电子邮件只需 3-4 行代码。但是,我正在寻找验证电子邮件 without using Regex. 在某种程度上,代码成功通过了几乎所有的验证,但是,仍然无法弄清楚 -如何避免特殊字符成为电子邮件地址的第一个和最后一个字符。

特殊字符列表 = '!', '#', '$', '%', '^', '&', '*', '(', ')', '-', '/', '~', '[', ']' ;

我看到的是:

如果用户名部分 (abc.xyz@gmail.com) 以 任何特殊字符,它应该触发 “无效的电子邮件 地址”错误。域部分也是如此。

例如...下面的email-IDs列表应该打印一个“无效的email ID” error message

#abc.xyz@gmail.com

abc.xyz&@gmail.com

abc.xyz&@!gmail.com

abc.xyz&@gmail.com!

import java.util.Scanner;

public class Email_Validation 

    public static void main(String[] args) 

        // User-input code
        Scanner scan = new Scanner(System.in);
        System.out.println("Enter your email address");
        String email = scan.next();

        // Code to check if email ends with '.' (period sign) 
        boolean checkEndDot  = false;
        checkEndDot = email.endsWith(".");

        // Code to find out last index of '@' sign
        int indexOfAt = email.indexOf('@');
        int lastIndexOfAt = email.lastIndexOf('.');


        //Code to check occurence of @ in the email address  
        int countOfAt = 0;

        for (int i = 0; i < email.length(); i++) 
            if(email.charAt(i)=='@')
                countOfAt++; 


        // Code to check occurence of [period sign i..e, "."] after @ 
        String buffering = email.substring(email.indexOf('@')+1, email.length());
        int len = buffering.length();

        int countOfDotAfterAt = 0;
        for (int i=0; i < len; i++) 
            if(buffering.charAt(i)=='.')
                countOfDotAfterAt++; 


// Code to print userName & domainName
            String userName = email.substring(0, email.indexOf('@'));
            String domainName = email.substring(email.indexOf('@')+1, email.length());

                System.out.println("\n");   

               if ((countOfAt==1) && (userName.endsWith(".")==false)  && (countOfDotAfterAt ==1) &&   
                  ((indexOfAt+3) <= (lastIndexOfAt) && !checkEndDot)) 

                   System.out.println("\"Valid email address\"");

               else        
                        System.out.println("\n\"Invalid email address\""); 


                System.out.println("\n");
                System.out.println("User name: " +userName+ "\n" + "Domain name: " +domainName);


    

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

这个怎么样:

public class EmailMe 
  private static Set<Character> bad = new HashSet<>();

  public static void main(String[] args) 
    char[] specialChars = new char[] '!', '#', '$', '%', '^', '&', '*', '(', ')', '-', '/', '~', '[', ']' ;
    for (char c : specialChars) 
      bad.add(c);
    
    check("#abc.xyz@gmail.com");
    check("abc.xyz&@gmail.com");
    check("abc.xyz&@!gmail.com");
    check("abc.xyz&@gmail.com!");
  

  public static void check(String email) 
    String name = email.substring(0, email.indexOf('@'));
    String domain = email.substring(email.indexOf('@')+1, email.length());
//    String[] split = email.split("@");
    checkAgain(name);
    checkAgain(domain);
  


  public static void checkAgain(String part) 
    if (bad.contains(part.charAt(0))) System.out.println("bad start:"+part);
    if (bad.contains(part.charAt(part.length()-1))) System.out.println("bad end:"+part);
  

【讨论】:

它确实为您提供了输出,但不是我想要的方式。所以,我对使用它有点怀疑,因为我正在寻找一种解决方案,在 @ 987654322@ 如果它一直使用正则表达式,解决方案会非常简单,最后,它不会在这里找到空间。 您自己的示例代码会找到“@”字符并使用该索引来获取@字符之后的部分。只需用该代码替换 email.split() 并获取之前和之后的部分。那么就没有“正则表达式的提示”了。 Thanks mate... 我不得不对您的代码进行一些更改以适应现有代码,但最后,它就像一个魅力.. !! !【参考方案2】:

所以,看看 String API。 http://docs.oracle.com/javase/7/docs/api/java/lang/String.html

具体来说,你有 String.length() 和 String.charAt()。因此,您可以非常非常轻松地从 String 中获取第一个和最后一个字符。您已经在代码中执行此操作;假设你已经得到它。

你可以在这里运行一个很长的 if 语句;

char first = email.charAt(0);
if (first == '!' || first == '#' || <more here>)  
    return false;

但这可能会让人头疼。另一种方法是使用 Set,如果您需要多次检查,这会更有效。 (查找 HashSet 通常很快。)例如,您可以创建一次集合,然后就可以通过 Set.contains(first) 多次使用它。

【讨论】:

但是,我看到的是特殊字符不应该是第一个或最后一个字符。 (同时适用于 - 用户名和域部分) 如何使用 HashSet 实现相同的功能? 对于最后一个字符,用 email.charAt(email.size() - 1) 再做一次。 对于 Set,创建一个 HashSet,放入所有特殊字符,而不是一个大的“if”语句,你可以检查 hashSet.contains(firstCharacter) 和 hashSet.contains(lastCharacter )。 但这里的问题是,电子邮件地址是作为User-input 出现的,而不是作为集合框架的一部分。那么,如何使用 hash.contains() method 进行检查? 对于集合框架,我仍然很天真If you could explain with the help of some code, it would be easy to co-relate things &amp; thereby help in understanding things smoothly.【参考方案3】:

我使用 Apache Commons 库中的 EmailValidator。 上面的例子,

String email = "anEmailAddress@domain.com";
EmailValidator validator = EmailValidator.getInstance();
if (!validator.isValid(email)) 
   // The email is not valid.

if (!EmailValidator.getInstance().isValid("anEmailAddress@domain.com")) 
   // The email is not valid.

如果你使用的是maven那么你可以使用this dependency,

<dependency>
    <groupId>commons-validator</groupId>
    <artifactId>commons-validator</artifactId>
    <version>1.4.0</version>
    <type>jar</type>
</dependency>

【讨论】:

【参考方案4】:

检查下面的代码,我相信它满足您的电子邮件验证。

Apache common lang maven dependency.

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.4</version>
</dependency>

Java 电子邮件验证实用程序代码。

public class EmailValidationUtility 


    private static final String[] SPECIAL_CHARACTERS_FOR_USERNAME = new String[] 
                "..", "__", ",", "/", "<", ">", "?", ";", ":", "\"", "\"",
                "", "", "[", "]", "|", "\\", "!", "@", "#", "$", "%", "^",
                "&", "*", "(", ")", "+", "=", "~", "`" ;

    private static final char[] SPECIAL_CHARACTERS_WITH_NUMBERS = new char[] 
                '.', ',', '/', '<', '>', '?', ';', ':', '\'', '\"', '',
                '', '[', ']', '|', '\\', '!', '@', '#', '$', '%', '^', '&',
                '*', '(', ')', '-', '_', '+', '=', '~', '`', '1', '2', '3',
                '4', '5', '6', '7', '8', '9', '0' ;

    /**
     * Method to validate the input email is valid or not.
     *
     * @param email the email
     * @return true, if is email valid
     */
    public static boolean isEmailValid(String email) 
        String[] emailChunks = StringUtils
                        .splitByWholeSeparatorPreserveAllTokens(email,
                                        "@");

        if (emailChunks.length != 2 || isEmailUserNameInvalid(emailChunks[0])
                        || StringUtils.isBlank(emailChunks[1])) 
            return false;
        

        String[] domainNames = StringUtils
                        .splitByWholeSeparatorPreserveAllTokens(emailChunks[1],
                                        ".");
        if (domainNames.length < 2) 
            return false;
        

        int topLevelDomainNameIndex = domainNames.length - 1;
        if (isTopLevelDomainNameInvalid(domainNames[topLevelDomainNameIndex])) 
            return false;
        

        domainNames = ArrayUtils.remove(domainNames, topLevelDomainNameIndex);

        return (isDomainNameValid(domainNames));
    



    private static boolean isEmailUserNameInvalid(String emailUserName) 
        return (StringUtils.isBlank(emailUserName) || StringUtils.containsAny(
                        emailUserName, SPECIAL_CHARACTERS_FOR_USERNAME));
    


    private static boolean isTopLevelDomainNameInvalid(String topLevelDomain) 
        return (StringUtils.isBlank(topLevelDomain) || StringUtils.containsAny(
                        topLevelDomain, SPECIAL_CHARACTERS_WITH_NUMBERS));
    
    
    private static boolean isDomainNameValid(String[] domainNames) 
        for (String domainName : domainNames) 
            if ((StringUtils.isBlank(domainName) || StringUtils.containsAny(
                            domainName, SPECIAL_CHARACTERS_WITH_NUMBERS))) 
                return false;
            
        
        return true;
    

【讨论】:

以上是关于不使用正则表达式的 Java 电子邮件验证的主要内容,如果未能解决你的问题,请参考以下文章

java电子邮件提取正则表达式?

使用正则表达式验证电子邮件

JAVA中写邮箱格式的正则表达式,怎么写?

Java 中的正则表达式电子邮件验证问题

电子邮件正则表达式验证器,不允许“。”

ASP.NET 电子邮件验证器正则表达式