validation email - Was ist die beste Validierungsmethode für Java-E-Mail-Adressen?





regex emailvalidator (20)


There don't seem to be any perfect libraries or ways to do this yourself, unless you have to time to send an email to the email address and wait for a response (this might not be an option though). I ended up using a suggestion from here http://blog.logichigh.com/2010/09/02/validating-an-e-mail-address/ and adjusting the code so it would work in Java.

public static boolean isValidEmailAddress(String email) {
    boolean stricterFilter = true; 
    String stricterFilterString = "[A-Z0-9a-z._%+-][email protected][A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    String laxString = "[email protected]+\\.[A-Za-z]{2}[A-Za-z]*";
    String emailRegex = stricterFilter ? stricterFilterString : laxString;
    java.util.regex.Pattern p = java.util.regex.Pattern.compile(emailRegex);
    java.util.regex.Matcher m = p.matcher(email);
    return m.matches();
}

Was sind die Bibliotheken für die Validierung von E-Mail-Adressen für Java? Gibt es Alternativen zum Commons Validator ?




/*to validate email id without using regex and packages and followed by your validate symbol and domain extensions u can add ... on below try1,holly methods */

import java.util.Scanner;
public test extends Exception
{
}
public class demo extends test
{
    public static boolean try1(char s)
    {
        boolean k = false;
         char[] d={'-','_','.'};//add valid Symbols
         for(int i=0;i<d.length;i++)
         {

             if( s==d[i])
             {
               k=true; 
             }
         }

        return k; 
    }
    public static boolean holly(String s) throws test
    {
         int i=s.lastIndexOf(".");
         int j=s.length();
         String o=s.substring(i+1,j);
         boolean d=false;
         String[] g={"co","in","com","org","net"};//add domain name extenstions
        for(int k=0;k<g.length;k++)
        {
            if(g[k].equals(o))
            {

                d=true;

            }
        }

        if(d==false)
        {
            throw new test();
        }
        return d;

    }
    public static void main(String[] args)
    {
        try
        {
          Scanner s=new Scanner(System.in);
          System.out.println("enter the email no of.id ");
           int n=s.nextInt();
           String[] id=new String[n];
            for(int i=0;i<n;i++)
             {
                 int l=0;
               id[i]=s.next();
               int c=1,c1=0;
                for(int k=c1;k<c;k++)
                    {
                        String b=id[k].toLowerCase();
                        boolean l1=holly(b);
                        if(id[k]==b)
                            {
                            System.out.println(b);
                            }
                    }c1++;
                      int x = 0;
                int count=0,count1=0;
                 char[] a=id[i].toCharArray();
                int g=0;
                 for(int j=0;j<a.length;j++)
                     {

                       if(Character.isLetterOrDigit(a[j]))
                        {
                         }
                       else     
                           {
                              if(a[j]=='@')
                               {
                                count++; 
                             }                       

                         else  
                             {
                              if(Character.isLetterOrDigit(a[j+1]))
                              {

                              }
                              else
                                  throw new test();
                             if(count==1)
                                {
                                  if(a[j]=='.')
                                   {
                                     l++; 
                                    }
                                 }
                              boolean z=try1(a[j]);

                                if(z==true)
                                {
                                }
                                else
                                    g=1;


                               }
                             }

                     }
                                     if(g==1)
                                       {
                                           throw new test();
                                       }
                                    if(count==0)
                                        {
                                            throw new test(); 
                                        }
                                    else if(count==2)
                                    {
                                        throw new test(); 
                                    }



                                    if(l==0)
                                        {
                                            throw new test(); 
                                        }
                    c++;


             }

    }
        catch(test ex)
        {
            System.out.println("enter the id is not correct");
        }
    }
}



Spät zur Frage, hier, aber: Ich unterhalte eine Klasse an dieser Adresse: http://lacinato.com/cm/software/emailrelated/emailaddress

Es basiert auf Les Hazlewoods Klasse, hat aber zahlreiche Verbesserungen und behebt einige Bugs. Apache-Lizenz.

Ich glaube, es ist der leistungsfähigste E-Mail-Parser in Java, und ich muss noch einen fähigen in jeder Sprache sehen, obwohl es einen da draußen gibt. Es ist kein Lexer-artiger Parser, sondern verwendet einige komplizierte Java-Regex und ist daher nicht so effizient, wie es sein könnte, aber meine Firma hat weit über 10 Milliarden reale Adressen damit analysiert: Es ist sicherlich in einer Hochleistung verwendbar Lage. Vielleicht einmal pro Jahr wird es eine Adresse treffen, die einen Regex-Stack-Überlauf verursacht (dies ist angemessen), aber dies sind Spam-Adressen, die Hunderte oder Tausende von Zeichen lang sind, mit vielen Anführungszeichen und Klammern und dergleichen.

RFC 2822 und die zugehörigen Spezifikationen sind in Bezug auf E-Mail-Adressen wirklich ziemlich freizügig, so dass eine Klasse wie diese für die meisten Anwendungen übertrieben ist. Zum Beispiel ist das folgende eine legitime Adresse, gemäß Spezifikation, Leerzeichen und allem:

"<bob \" (here) " < (hi there) "bob(the man)smith" (hi) @ (there) example.com (hello) > (again)

Kein Mailserver würde dies erlauben, aber diese Klasse kann es analysieren (und in ein verwendbares Formular umschreiben).

Wir haben festgestellt, dass die vorhandenen Java-E-Mail-Parseroptionen nicht ausreichend haltbar sind (das heißt, sie konnten nicht alle gültigen Adressen analysieren). Daher haben wir diese Klasse erstellt.

Der Code ist gut dokumentiert und verfügt über viele einfach zu ändernde Optionen, um bestimmte E-Mail-Formulare zuzulassen oder zu sperren. Es bietet auch eine Vielzahl von Methoden, um auf bestimmte Teile der Adresse (linke Seite, rechte Seite, persönliche Namen, Kommentare usw.) zuzugreifen, um Mailbox-Listen-Header zu analysieren / zu validieren, um den Rückpfad zu analysieren / validieren (was unter den Headern einzigartig ist) und so weiter.

Der Code, wie er geschrieben wurde, hat eine Javamail-Abhängigkeit, aber er kann leicht entfernt werden, wenn Sie die kleinere Funktionalität, die er bietet, nicht möchten.




This is the best method:

public static boolean isValidEmail(String enteredEmail){
        String EMAIL_REGIX = "^[\\\\w!#$%&’*+/=?`{|}~^-]+(?:\\\\.[\\\\w!#$%&’*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\\\.)+[a-zA-Z]{2,6}$";
        Pattern pattern = Pattern.compile(EMAIL_REGIX);
        Matcher matcher = pattern.matcher(enteredEmail);
        return ((!enteredEmail.isEmpty()) && (enteredEmail!=null) && (matcher.matches()));
    }

Sources:- howtodoinjava.com/2014/11/11/java-regex-validate-email-address

http://www.rfc-editor.org/rfc/rfc5322.txt




Am einfachsten ist es, das offizielle Java-E-Mail-Paket zu verwenden :

public static boolean isValidEmailAddress(String email) {
   boolean result = true;
   try {
      InternetAddress emailAddr = new InternetAddress(email);
      emailAddr.validate();
   } catch (AddressException ex) {
      result = false;
   }
   return result;
}



Les Hazlewood hat eine sehr gründliche RFC 2822-konforme E-Mail-Validierungsklasse mit regulären Java-Ausdrücken geschrieben. Sie finden es unter http://www.leshazlewood.com/?p=23 . Seine Gründlichkeit (oder die Implementierung von Java RE) führt jedoch zu Ineffizienz - lesen Sie die Kommentare zu Parsing-Zeiten für lange Adressen.




Wenn Sie überprüfen VRFY , ob eine E-Mail-Adresse gültig ist, erhalten Sie von VRFY einen Teil des Weges. Ich habe festgestellt, dass es für die Validierung von Intranet- Adressen ( dh E-Mail-Adressen für interne Sites) nützlich ist. Es ist jedoch weniger nützlich für Internet-Mail-Server (siehe die Vorbehalte oben auf dieser Seite)




Apache Commons ist allgemein als solides Projekt bekannt. Denken Sie jedoch daran, dass Sie immer noch eine Bestätigungs-E-Mail an die Adresse senden müssen, wenn Sie sicherstellen möchten, dass es sich um eine echte E-Mail handelt und dass der Inhaber möchte, dass sie auf Ihrer Website verwendet wird.

BEARBEITEN : Es gab einen bug bei dem die Domain zu restriktiv war und keine gültigen E-Mails von neuen TLDs akzeptiert wurden.

Dieser Fehler wurde am 03 / Jan / 15 02:48 in commons- validator Version 1.4.1 behoben




public class Validations {

    private Pattern regexPattern;
    private Matcher regMatcher;

    public String validateEmailAddress(String emailAddress) {

        regexPattern = Pattern.compile("^[(a-zA-Z-0-9-\\_\\+\\.)][email protected][(a-z-A-z)]+\\.[(a-zA-z)]{2,3}$");
        regMatcher   = regexPattern.matcher(emailAddress);
        if(regMatcher.matches()) {
            return "Valid Email Address";
        } else {
            return "Invalid Email Address";
        }
    }

    public String validateMobileNumber(String mobileNumber) {
        regexPattern = Pattern.compile("^\\+[0-9]{2,3}+-[0-9]{10}$");
        regMatcher   = regexPattern.matcher(mobileNumber);
        if(regMatcher.matches()) {
            return "Valid Mobile Number";
        } else {
            return "Invalid Mobile Number";
        }
    }

    public static void main(String[] args) {

        String emailAddress = "[email protected]";
        String mobileNumber = "+91-9986571622";
        Validations validations = new Validations();
        System.out.println(validations.validateEmailAddress(emailAddress));
        System.out.println(validations.validateMobileNumber(mobileNumber));
    }
}



Aktuelle Apache Commons Validator-Version ist 1.3.1 .

Validierende Klasse ist org.apache.commons.validator.EmailValidator. Es hat einen Import für org.apache.oro.text.perl.Perl5Util, der aus einem zurückgezogenen Jakarta ORO-Projekt stammt .

BTW, ich habe festgestellt, dass es eine Version 1.4 gibt, hier sind die API-Dokumente . Auf der site heißt es: "Letzte Veröffentlichung: 05. März 2008 | Version: 1.4-SNAPSHOT", aber das ist nicht endgültig. Nur eine Möglichkeit, sich selbst zu bauen (aber das ist ein Schnappschuss, nicht RELEASE) und verwenden, oder von here herunterladen. Dies bedeutet, dass 1.4 nicht für drei Jahre (2008-2011) abgeschlossen wurde. Dies ist nicht im Stil von Apache. Ich suche nach einer besseren Option, aber fand keine, die sehr adoptiert ist. Ich möchte etwas verwenden, das gut getestet ist, will keine Bugs treffen.




public void EmailCheck(View v) // This is pattern method import by regular class
{
    String str = "";
    emailid = emailID.getText().toString();

    if(emailid.equalsIgnoreCase(str))
    {
        System.out.println("Please enter your email id");
     }
    else
    {
        Pattern p =Pattern.compile("[a-zA-Z0-9_.]*@[a-zA-Z]*.[a-zA-Z]*");
        Matcher m = p.matcher(emailid);
        boolean bm = m.matches();

        if(bm == true)
        {
            System.out.println("email id is valid");

        }
        else
        {
            System.out.println("email id is Invalid, Re-try again");

        }
    }
}






Späte Antwort, aber ich denke, es ist einfach und würdig:

    public boolean isValidEmailAddress(String email) {
           String ePattern = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-][email protected]((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$";
           java.util.regex.Pattern p = java.util.regex.Pattern.compile(ePattern);
           java.util.regex.Matcher m = p.matcher(email);
           return m.matches();
    }

Testfälle :

Zu Produktionszwecken sollten Domain-Name-Validierungen netzwerkweise durchgeführt werden.




Ich habe eine Klasse früher für eine Android-Anwendung gemacht, die Sie vielleicht nützlich finden

package com.amit.parking.parking.Analytics;

import android.widget.EditText;

import java.util.ArrayList;

/**
 * Created by Android Developer on 3/1/2015.
 */
public class EmailValidator {

private static String email;
private static int count = 0;


private static final Character [] alphabeticSmall = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
private static final Character [] alphabeticLarge = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
private static final Character [] forbiddenSymbols = {
        '\'','^','[',',','!','#','$','%','&','*','+','/','=',
        '?','`','{','|','}','~',']','(',')',':','\\',' ','÷'
        ,'×','؛','<','>','|',';','"','₩','¥','£','€','`','°'
        ,'•','○','●','□','■','♤','♡','♢','♧','☆','¤','《',
        '》','¡','¿'
};

private String[] validEnds = {"ac", "ad", "ae", "aero", "af", "ag", "ai",
        "al", "am", "an", "ao", "aq", "ar", "arpa", "as", "asia", "at", "au",
        "aw", "ax", "az", "ba", "bb", "bd", "be", "bf", "bg", "bh", "bi", "biz",
        "bj", "bm", "bn", "bo", "br", "bs", "bt", "bv", "bw", "by", "bz", "ca",
        "cat", "cc", "cd", "cf", "cg", "ch", "ci", "ck", "cl", "cm", "cn", "co",
        "com", "coop", "cr", "cu", "cv", "cx", "cy", "cz", "de", "dj", "dk",
        "dm", "do", "dz", "ec", "edu", "ee", "eg", "er", "es", "et", "eu", "fi",
        "fj", "fk", "fm", "fo", "fr", "ga", "gb", "gd", "ge", "gf", "gg", "gh",
        "gi", "gl", "gm", "gn", "gov", "gp", "gq", "gr", "gs", "gt", "gu", "gw",
        "gy", "hk", "hm", "hn", "hr", "ht", "hu", "id", "ie", "il", "im", "in",
        "info", "int", "io", "iq", "ir", "is", "it", "je", "jm", "jo", "jobs",
        "jp", "ke", "kg", "kh", "ki", "km", "kn", "kp", "kr", "kw", "ky", "kz",
        "la", "lb", "lc", "li", "lk", "lr", "ls", "lt", "lu", "lv", "ly", "ma",
        "mc", "md", "me", "mg", "mh", "mil", "mk", "ml", "mm", "mn", "mo",
        "mobi", "mp", "mq", "mr", "ms", "mt", "mu", "museum", "mv", "mw", "mx",
        "my", "mz", "na", "name", "nc", "ne", "net", "nf", "ng", "ni", "nl",
        "no", "np", "nr", "nu", "nz", "om", "org", "pa", "pe", "pf", "pg", "ph",
        "pk", "pl", "pm", "pn", "pr", "pro", "ps", "pt", "pw", "py", "qa", "re",
        "ro", "rs", "ru", "rw", "sa", "sb", "sc", "sd", "se", "sg", "sh", "si",
        "sj", "sk", "sl", "sm", "sn", "so", "sr", "st", "su", "sv", "sy", "sz",
        "tc", "td", "tel", "tf", "tg", "th", "tj", "tk", "tl", "tm", "tn", "to",
        "tp", "tr", "travel", "tt", "tv", "tw", "tz", "ua", "ug", "uk", "um",
        "us", "uy", "uz", "va", "vc", "ve", "vg", "vi", "vn", "vu", "wf", "ws",
        "ye", "yt", "yu", "za", "zm", "zw"};

private static ArrayList<Character> correctSmallLetters;
private static ArrayList<Character> correctLargeLetters;
private static ArrayList<Character> forbiddenSymbolsArray;

private static CharSequence cleanText = "";
private static CharSequence [] cleanTextToArray;

private static int dynamicArraySize = 1;
private static Character [] dynamicArray;

public EmailValidator(String email){
    this.email = email;
    correctSmallLetters = new ArrayList<>();
    correctLargeLetters = new ArrayList<>();
    forbiddenSymbolsArray = new ArrayList<>();
}

public static boolean isEmailCharactersValidated(){
        if(equalsGetSmallLetters() || equalsGetLargeLetters()){
            return true;
        }
        return false;
}

private static boolean equalsGetSmallLetters() {
    count = 0;
    while(count < email.length()) {
        for (int smallLetterIndex = 0; smallLetterIndex < alphabeticSmall.length; smallLetterIndex++) {

            if(email.charAt(count) == alphabeticSmall[smallLetterIndex]){
                correctSmallLetters.add(email.charAt(count));
            }
        }
        count++;
    }
    count = 0;
    return correctSmallLetters.size() > 0;
}

private static boolean equalsGetLargeLetters() {
    count = 0;
    while(count < email.length()) {
        for (int largeLetterIndex = 0; largeLetterIndex < alphabeticLarge.length; largeLetterIndex++) {

            if(email.charAt(count) == alphabeticLarge[largeLetterIndex]){
                correctLargeLetters.add(email.charAt(count));
            }
        }
        count++;
    }
    count = 0;
    return correctLargeLetters.size() > 0;
}

public static boolean isEmailHasForbiddenSymbols(){
    count = 0;
    while(count < email.length()) {
        for (int symbolIndex = 0; symbolIndex < forbiddenSymbols.length; symbolIndex++) {

            if(email.charAt(count) == forbiddenSymbols[symbolIndex]){
                forbiddenSymbolsArray.add(email.charAt(count));
                //addToTheDynamicArray(email.charAt(count));
            }

        }
        count++;
    }
    count = 0;

    return forbiddenSymbolsArray.size() > 0;
}

/* THIS IS JUST A TEST METHOD... */
private static void addToTheDynamicArray(Character c){

    dynamicArray = new Character[dynamicArraySize];

    if (dynamicArray.length == 1) {
        dynamicArray[dynamicArraySize -1] = c;
        dynamicArraySize++;
    } else {
        dynamicArray = new Character[dynamicArraySize];
        dynamicArray[dynamicArraySize -1] = c;
        dynamicArraySize++;
    }
}

public static void removeForbiddenSymbols(EditText etEmail){

    try {
        count = 0;
        while (count < etEmail.getText().toString().length()) {
            for (int symbolIndex = 0; symbolIndex < forbiddenSymbols.length; symbolIndex++) {

                if (etEmail.getText().toString().charAt(count) == forbiddenSymbols[symbolIndex]) {
                    etEmail.setText(etEmail.getText().toString().replace(String.valueOf(etEmail.getText().toString().charAt(count)), ""));
                }
            }
            count++;
        }
        count = 0;
    }catch (Exception ignored) { }
}

public boolean isEmailCorrect() {return checkForAts() && checkForDots();}

private boolean checkForAts() {
    int atsCount = 0;
    ArrayList<Character> ats = new ArrayList<>();

    while(atsCount < email.length()){
        if(email.charAt(atsCount) == '@'){
            ats.add(email.charAt(atsCount));
        }
        atsCount++;
    }

    return ats.size() == 1;
}

public boolean isEmailHasValidEnd(){
    int validEndsCount = 0;
    int emailCharsCount = 0;
    while (emailCharsCount < email.length()){

        while(validEndsCount < validEnds.length){


            if(email.endsWith(validEnds[validEndsCount]))
                return true;

            validEndsCount++;
        }

        emailCharsCount++;
    }


    return false;
}

private boolean checkForDots() {
    int dotsCount = 0;
    ArrayList<Character> dots = new ArrayList<>();

    while(dotsCount < email.length()){
        if(email.charAt(dotsCount) == '.'){
            dots.add(email.charAt(dotsCount));
        }
        dotsCount++;
    }

    return dots.size() == 1;
}

public boolean isValidEmailAddress(String email) {
    String ePattern = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-][email protected]((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$";
    java.util.regex.Pattern p = java.util.regex.Pattern.compile(ePattern);
    java.util.regex.Matcher m = p.matcher(email);
    return m.matches();
}

}




Der Apache Commons-Validator kann wie in den anderen Antworten erwähnt verwendet werden.

pom.xml:

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

build.gradle:

compile 'commons-validator:commons-validator:1.4.1'

Der Import:

import org.apache.commons.validator.routines.EmailValidator;

Der Code:

String email = "[email protected]";
boolean valid = EmailValidator.getInstance().isValid(email);

und um lokale Adressen zuzulassen

boolean allowLocal = true;
boolean valid = EmailValidator.getInstance(allowLocal).isValid(email);



You may also want to check for the length - emails are a maximum of 254 chars long. I use the apache commons validator and it doesn't check for this.




This is the simplest way to do it, without any regular expressions or Object-Armageddon.

"[email protected]" = 0

" [email protected] " = 0 vorlaufende und nachlaufende Leerzeichen werden unterdrueckt

"[email protected]" = 0 Zeichen "_" und "-" duerfen vorkommen

"[email protected]" = 0 minimal gueltige Laenge sind 6 Zeichen

"[email protected]@GHI.JKL" = 11 doppeltes AT-Zeichen

"[email protected]" = 5 Start auf .

"[email protected]" = 16 Ende auf .

"[email protected]" = 13 Keinen Punkt gefunden

"[email protected]" = 10 [email protected]

"[email protected]" = 9 @.

"[email protected]" = 3 Zahl nach dem AT-Zeichen

"[email protected]_HI.JKL" = 3 Sonderzeichen nach dem AT-Zeichen

"[email protected]" = 4 keine 2 Punkte nacheinander

"[email protected]" = 8 kein AT-Zeichen am Ende

"[email protected]" = 17 Top-Level-Domain muss 2 Stellen haben

null = 1 Eingabestring nicht gesetzt

" " = 2 durch TRIM eine Laenge von 0

" A . B & C . D " = 12 Leerzeichen innerhalb der eMail-Adresse

"(?).[!]@{&}.: " = 12 Sonderzeichen sind nicht erlaubt

  public static int checkEMailAdresse( String pEingabe )
  {
    if ( pEingabe == null ) return 1; // Eingabe ist null

    String pruef_str = pEingabe.trim();

    int len_pruef_str = pruef_str.length();

    if ( ( len_pruef_str < 6 ) || ( len_pruef_str > 254 ) ) return 2; // Laengenbegrenzungen

    int pos_at_zeichen = -1;

    int letzter_punkt = -1;

    int zeichen_zaehler = 0;

    int akt_index = 0;

    while ( akt_index < len_pruef_str )
    {
      char aktuelles_zeichen = pruef_str.charAt( akt_index );

      if ( ( ( aktuelles_zeichen >= 'a' ) && ( aktuelles_zeichen <= 'z' ) ) || ( ( aktuelles_zeichen >= 'A' ) && ( aktuelles_zeichen <= 'Z' ) ) )
      {
        zeichen_zaehler++;
      }
      else if ( ( ( aktuelles_zeichen >= '0' ) && ( aktuelles_zeichen <= '9' ) ) || ( aktuelles_zeichen == '_' ) || ( aktuelles_zeichen == '-' ) )
      {
        if ( zeichen_zaehler == 0 ) return 3; // Zahl oder Sonderzeichen nur nach einem Zeichen hinter ABC (Teilstring darf nicht mit Zahl oder Sonderzeichen beginnen)
      }
      else if ( aktuelles_zeichen == '.' )
      {
        if ( letzter_punkt == -1 )
        {
          if ( akt_index == 0 ) return 5; // kein Beginn mit einem Punkt
        }
        else
        {
          if ( akt_index - letzter_punkt == 1 ) return 4; // keine zwei Punkte hintereinander
        }

        letzter_punkt = akt_index;

        zeichen_zaehler = 0;
      }
      else if ( aktuelles_zeichen == '@' )
      {
        if ( pos_at_zeichen == -1 )
        {
          if ( akt_index == 0 ) return 6; // kein AT-Zeichen am Anfang

          if ( akt_index > 64 ) return 7; // RFC 5321 ==> SMTP-Protokoll ==> maximale Laenge des Local-Parts sind 64 Bytes

          if ( ( akt_index + 1 ) == len_pruef_str ) return 8; // kein AT-Zeichen am Ende

          if ( akt_index - letzter_punkt == 1 ) return 10; // ungueltige Zeichenkombination "[email protected]"

          if ( pruef_str.charAt( akt_index + 1 ) == '.' ) return 9; // ungueltige Zeichenkombination "@."

          pos_at_zeichen = akt_index;

          zeichen_zaehler = 0;
        }
        else
        {
          return 11; // kein weiteres AT-Zeichen zulassen, wenn schon AT-Zeichen gefunden wurde
        }
      }
      else
      {
        return 12; // ungueltiges Zeichen in der Eingabe gefunden 
      }

      akt_index++;
    }

    if ( letzter_punkt == -1 ) return 13; // keinen Punkt gefunden (Es muss mindestens ein Punkt fuer den Domain-Trenner vorhanden sein)

    if ( pos_at_zeichen == -1 ) return 14; // kein AT-Zeichen gefunden

    if ( letzter_punkt < pos_at_zeichen ) return 15; // der letzte Punkt muss nach dem AT-Zeichen liegen (... hier eben die negative Form, wenn der letzte Punkt vor dem AT-Zeichen stand ist es ein Fehler)

    if ( ( letzter_punkt + 1 ) == len_pruef_str ) return 16; // der letzte Punkt darf nicht am Ende liegen

    if ( ( letzter_punkt + 1 ) > ( len_pruef_str - 2 ) ) return 17; // Top-Level-Domain muss mindestens 2 Stellen lang sein.

    return 0; 
  }



Ich habe einen Teil des Codes in Zend_Validator_Email portiert:

@FacesValidator("emailValidator")
public class EmailAddressValidator implements Validator {

    private String localPart;
    private String hostName;
    private boolean domain = true;

    Locale locale;
    ResourceBundle bundle;

    private List<FacesMessage> messages = new ArrayList<FacesMessage>();

    private HostnameValidator hostnameValidator;

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        setOptions(component);
        String email    = (String) value;
        boolean result  = true;
        Pattern pattern = Pattern.compile("^(.+)@([^@]+[^.])$");
        Matcher matcher = pattern.matcher(email);

        locale = context.getViewRoot().getLocale();
        bundle = ResourceBundle.getBundle("com.myapp.resources.validationMessages", locale);

        boolean length = true;
        boolean local  = true;

        if (matcher.find()) {
            localPart   = matcher.group(1);
            hostName    = matcher.group(2);

            if (localPart.length() > 64 || hostName.length() > 255) {
                length          = false;
                addMessage("enterValidEmail", "email.AddressLengthExceeded");
            } 

            if (domain == true) {
                hostnameValidator = new HostnameValidator();
                hostnameValidator.validate(context, component, hostName);
            }

            local = validateLocalPart();

            if (local && length) {
                result = true;
            } else {
                result = false;
            }

        } else {
            result          = false;
            addMessage("enterValidEmail", "invalidEmailAddress");
        }

        if (result == false) {
            throw new ValidatorException(messages);
        }

    }

    private boolean validateLocalPart() {
        // First try to match the local part on the common dot-atom format
        boolean result = false;

        // Dot-atom characters are: 1*atext *("." 1*atext)
        // atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*",
        //        "+", "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~"
        String atext = "a-zA-Z0-9\\u0021\\u0023\\u0024\\u0025\\u0026\\u0027\\u002a"
                + "\\u002b\\u002d\\u002f\\u003d\\u003f\\u005e\\u005f\\u0060\\u007b"
                + "\\u007c\\u007d\\u007e";
        Pattern regex = Pattern.compile("^["+atext+"]+(\\u002e+["+atext+"]+)*$");
        Matcher matcher = regex.matcher(localPart);
        if (matcher.find()) {
            result = true;
        } else {
            // Try quoted string format

            // Quoted-string characters are: DQUOTE *([FWS] qtext/quoted-pair) [FWS] DQUOTE
            // qtext: Non white space controls, and the rest of the US-ASCII characters not
            //   including "\" or the quote character
            String noWsCtl = "\\u0001-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f";
            String qText = noWsCtl + "\\u0021\\u0023-\\u005b\\u005d-\\u007e";
            String ws = "\\u0020\\u0009";

            regex = Pattern.compile("^\\u0022(["+ws+qText+"])*["+ws+"]?\\u0022$");
            matcher = regex.matcher(localPart);
            if (matcher.find()) {
                result = true;
            } else {
                addMessage("enterValidEmail", "email.AddressDotAtom");
                addMessage("enterValidEmail", "email.AddressQuotedString");
                addMessage("enterValidEmail", "email.AddressInvalidLocalPart");
            }
        }

        return result;
    }

    private void addMessage(String detail, String summary) {
        String detailMsg = bundle.getString(detail);
        String summaryMsg = bundle.getString(summary);
        messages.add(new FacesMessage(FacesMessage.SEVERITY_ERROR, summaryMsg, detailMsg));
    }

    private void setOptions(UIComponent component) {
        Boolean domainOption = Boolean.valueOf((String) component.getAttributes().get("domain"));
        //domain = (domainOption == null) ? true : domainOption.booleanValue();
    }
}

Mit einem Hostnamen-Validator wie folgt:

@FacesValidator("hostNameValidator")
public class HostnameValidator implements Validator {

    private Locale locale;
    private ResourceBundle bundle;
    private List<FacesMessage> messages;
    private boolean checkTld = true;
    private boolean allowLocal = false;
    private boolean allowDNS = true;
    private String tld;
    private String[] validTlds = {"ac", "ad", "ae", "aero", "af", "ag", "ai",
        "al", "am", "an", "ao", "aq", "ar", "arpa", "as", "asia", "at", "au",
        "aw", "ax", "az", "ba", "bb", "bd", "be", "bf", "bg", "bh", "bi", "biz",
        "bj", "bm", "bn", "bo", "br", "bs", "bt", "bv", "bw", "by", "bz", "ca",
        "cat", "cc", "cd", "cf", "cg", "ch", "ci", "ck", "cl", "cm", "cn", "co",
        "com", "coop", "cr", "cu", "cv", "cx", "cy", "cz", "de", "dj", "dk",
        "dm", "do", "dz", "ec", "edu", "ee", "eg", "er", "es", "et", "eu", "fi",
        "fj", "fk", "fm", "fo", "fr", "ga", "gb", "gd", "ge", "gf", "gg", "gh",
        "gi", "gl", "gm", "gn", "gov", "gp", "gq", "gr", "gs", "gt", "gu", "gw",
        "gy", "hk", "hm", "hn", "hr", "ht", "hu", "id", "ie", "il", "im", "in",
        "info", "int", "io", "iq", "ir", "is", "it", "je", "jm", "jo", "jobs",
        "jp", "ke", "kg", "kh", "ki", "km", "kn", "kp", "kr", "kw", "ky", "kz",
        "la", "lb", "lc", "li", "lk", "lr", "ls", "lt", "lu", "lv", "ly", "ma",
        "mc", "md", "me", "mg", "mh", "mil", "mk", "ml", "mm", "mn", "mo",
        "mobi", "mp", "mq", "mr", "ms", "mt", "mu", "museum", "mv", "mw", "mx",
        "my", "mz", "na", "name", "nc", "ne", "net", "nf", "ng", "ni", "nl",
        "no", "np", "nr", "nu", "nz", "om", "org", "pa", "pe", "pf", "pg", "ph",
        "pk", "pl", "pm", "pn", "pr", "pro", "ps", "pt", "pw", "py", "qa", "re",
        "ro", "rs", "ru", "rw", "sa", "sb", "sc", "sd", "se", "sg", "sh", "si",
        "sj", "sk", "sl", "sm", "sn", "so", "sr", "st", "su", "sv", "sy", "sz",
        "tc", "td", "tel", "tf", "tg", "th", "tj", "tk", "tl", "tm", "tn", "to",
        "tp", "tr", "travel", "tt", "tv", "tw", "tz", "ua", "ug", "uk", "um",
        "us", "uy", "uz", "va", "vc", "ve", "vg", "vi", "vn", "vu", "wf", "ws",
        "ye", "yt", "yu", "za", "zm", "zw"};
    private Map<String, Map<Integer, Integer>> idnLength;

    private void init() {
        Map<Integer, Integer> biz = new HashMap<Integer, Integer>();
        biz.put(5, 17);
        biz.put(11, 15);
        biz.put(12, 20);

        Map<Integer, Integer> cn = new HashMap<Integer, Integer>();
        cn.put(1, 20);

        Map<Integer, Integer> com = new HashMap<Integer, Integer>();
        com.put(3, 17);
        com.put(5, 20);

        Map<Integer, Integer> hk = new HashMap<Integer, Integer>();
        hk.put(1, 15);

        Map<Integer, Integer> info = new HashMap<Integer, Integer>();
        info.put(4, 17);

        Map<Integer, Integer> kr = new HashMap<Integer, Integer>();
        kr.put(1, 17);

        Map<Integer, Integer> net = new HashMap<Integer, Integer>();
        net.put(3, 17);
        net.put(5, 20);

        Map<Integer, Integer> org = new HashMap<Integer, Integer>();
        org.put(6, 17);

        Map<Integer, Integer> tw = new HashMap<Integer, Integer>();
        tw.put(1, 20);

        Map<Integer, Integer> idn1 = new HashMap<Integer, Integer>();
        idn1.put(1, 20);

        Map<Integer, Integer> idn2 = new HashMap<Integer, Integer>();
        idn2.put(1, 20);

        Map<Integer, Integer> idn3 = new HashMap<Integer, Integer>();
        idn3.put(1, 20);

        Map<Integer, Integer> idn4 = new HashMap<Integer, Integer>();
        idn4.put(1, 20);

        idnLength = new HashMap<String, Map<Integer, Integer>>();

        idnLength.put("BIZ", biz);
        idnLength.put("CN", cn);
        idnLength.put("COM", com);
        idnLength.put("HK", hk);
        idnLength.put("INFO", info);
        idnLength.put("KR", kr);
        idnLength.put("NET", net);
        idnLength.put("ORG", org);
        idnLength.put("TW", tw);
        idnLength.put("ایران", idn1);
        idnLength.put("中国", idn2);
        idnLength.put("公司", idn3);
        idnLength.put("网络", idn4);

        messages = new ArrayList<FacesMessage>();
    }

    public HostnameValidator() {
        init();
    }

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        String hostName = (String) value;

        locale = context.getViewRoot().getLocale();
        bundle = ResourceBundle.getBundle("com.myapp.resources.validationMessages", locale);

        Pattern ipPattern = Pattern.compile("^[0-9a-f:\\.]*$", Pattern.CASE_INSENSITIVE);
        Matcher ipMatcher = ipPattern.matcher(hostName);
        if (ipMatcher.find()) {
            addMessage("hostname.IpAddressNotAllowed");
            throw new ValidatorException(messages);
        }

        boolean result = false;

        // removes last dot (.) from hostname 
        hostName = hostName.replaceAll("(\\.)+$", "");
        String[] domainParts = hostName.split("\\.");

        boolean status = false;

        // Check input against DNS hostname schema
        if ((domainParts.length > 1) && (hostName.length() > 4) && (hostName.length() < 255)) {
            status = false;

            dowhile:
            do {
                // First check TLD
                int lastIndex = domainParts.length - 1;
                String domainEnding = domainParts[lastIndex];
                Pattern tldRegex = Pattern.compile("([^.]{2,10})", Pattern.CASE_INSENSITIVE);
                Matcher tldMatcher = tldRegex.matcher(domainEnding);
                if (tldMatcher.find() || domainEnding.equals("ایران")
                        || domainEnding.equals("中国")
                        || domainEnding.equals("公司")
                        || domainEnding.equals("网络")) {



                    // Hostname characters are: *(label dot)(label dot label); max 254 chars
                    // label: id-prefix [*ldh{61} id-prefix]; max 63 chars
                    // id-prefix: alpha / digit
                    // ldh: alpha / digit / dash

                    // Match TLD against known list
                    tld = (String) tldMatcher.group(1).toLowerCase().trim();
                    if (checkTld == true) {
                        boolean foundTld = false;
                        for (int i = 0; i < validTlds.length; i++) {
                            if (tld.equals(validTlds[i])) {
                                foundTld = true;
                            }
                        }

                        if (foundTld == false) {
                            status = false;
                            addMessage("hostname.UnknownTld");
                            break dowhile;
                        }
                    }

                    /**
                     * Match against IDN hostnames
                     * Note: Keep label regex short to avoid issues with long patterns when matching IDN hostnames
                     */
                    List<String> regexChars = getIdnRegexChars();

                    // Check each hostname part
                    int check = 0;
                    for (String domainPart : domainParts) {
                        // Decode Punycode domainnames to IDN
                        if (domainPart.indexOf("xn--") == 0) {
                            domainPart = decodePunycode(domainPart.substring(4));
                        }

                        // Check dash (-) does not start, end or appear in 3rd and 4th positions
                        if (domainPart.indexOf("-") == 0
                                || (domainPart.length() > 2 && domainPart.indexOf("-", 2) == 2 && domainPart.indexOf("-", 3) == 3)
                                || (domainPart.indexOf("-") == (domainPart.length() - 1))) {
                            status = false;
                            addMessage("hostname.DashCharacter");
                            break dowhile;
                        }

                        // Check each domain part
                        boolean checked = false;

                        for (int key = 0; key < regexChars.size(); key++) {
                            String regexChar = regexChars.get(key);
                            Pattern regex = Pattern.compile(regexChar);
                            Matcher regexMatcher = regex.matcher(domainPart);
                            status = regexMatcher.find();
                            if (status) {
                                int length = 63;

                                if (idnLength.containsKey(tld.toUpperCase())
                                        && idnLength.get(tld.toUpperCase()).containsKey(key)) {
                                    length = idnLength.get(tld.toUpperCase()).get(key);
                                }

                                int utf8Length;
                                try {
                                    utf8Length = domainPart.getBytes("UTF8").length;
                                    if (utf8Length > length) {
                                        addMessage("hostname.InvalidHostname");
                                    } else {
                                        checked = true;
                                        break;
                                    }
                                } catch (UnsupportedEncodingException ex) {
                                    Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
                                }


                            }
                        }


                        if (checked) {
                            ++check;
                        }
                    }

                    // If one of the labels doesn't match, the hostname is invalid
                    if (check != domainParts.length) {
                        status = false;
                        addMessage("hostname.InvalidHostnameSchema");

                    }
                } else {
                    // Hostname not long enough
                    status = false;
                    addMessage("hostname.UndecipherableTld");
                }

            } while (false);

            if (status == true && allowDNS) {
                result = true;
            }

        } else if (allowDNS == true) {
            addMessage("hostname.InvalidHostname");
            throw new ValidatorException(messages);
        }

        // Check input against local network name schema;
        Pattern regexLocal = Pattern.compile("^(([a-zA-Z0-9\\x2d]{1,63}\\x2e)*[a-zA-Z0-9\\x2d]{1,63}){1,254}$", Pattern.CASE_INSENSITIVE);
        boolean checkLocal = regexLocal.matcher(hostName).find();
        if (allowLocal && !status) {
            if (checkLocal) {
                result = true;
            } else {
                // If the input does not pass as a local network name, add a message
                result = false;
                addMessage("hostname.InvalidLocalName");
            }
        }


        // If local network names are not allowed, add a message
        if (checkLocal && !allowLocal && !status) {
            result = false;
            addMessage("hostname.LocalNameNotAllowed");
        }

        if (result == false) {
            throw new ValidatorException(messages);
        }

    }

    private void addMessage(String msg) {
        String bundlMsg = bundle.getString(msg);
        messages.add(new FacesMessage(FacesMessage.SEVERITY_ERROR, bundlMsg, bundlMsg));
    }

    /**
     * Returns a list of regex patterns for the matched TLD
     * @param tld
     * @return 
     */
    private List<String> getIdnRegexChars() {
        List<String> regexChars = new ArrayList<String>();
        regexChars.add("^[a-z0-9\\x2d]{1,63}$");
        Document doc = null;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);

        try {
            InputStream validIdns = getClass().getClassLoader().getResourceAsStream("com/myapp/resources/validIDNs_1.xml");
            DocumentBuilder builder = factory.newDocumentBuilder();
            doc = builder.parse(validIdns);
            doc.getDocumentElement().normalize();
        } catch (SAXException ex) {
            Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
        }

        // prepare XPath
        XPath xpath = XPathFactory.newInstance().newXPath();

        NodeList nodes = null;
        String xpathRoute = "//idn[tld=\'" + tld.toUpperCase() + "\']/pattern/text()";

        try {
            XPathExpression expr;
            expr = xpath.compile(xpathRoute);
            Object res = expr.evaluate(doc, XPathConstants.NODESET);
            nodes = (NodeList) res;
        } catch (XPathExpressionException ex) {
            Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
        }


        for (int i = 0; i < nodes.getLength(); i++) {
            regexChars.add(nodes.item(i).getNodeValue());
        }

        return regexChars;
    }

    /**
     * Decode Punycode string
     * @param encoded
     * @return 
         */
    private String decodePunycode(String encoded) {
        Pattern regex = Pattern.compile("([^a-z0-9\\x2d]{1,10})", Pattern.CASE_INSENSITIVE);
        Matcher matcher = regex.matcher(encoded);
        boolean found = matcher.find();

        if (encoded.isEmpty() || found) {
            // no punycode encoded string, return as is
            addMessage("hostname.CannotDecodePunycode");
            throw new ValidatorException(messages);
        }

        int separator = encoded.lastIndexOf("-");
            List<Integer> decoded = new ArrayList<Integer>();
        if (separator > 0) {
            for (int x = 0; x < separator; ++x) {
                decoded.add((int) encoded.charAt(x));
            }
        } else {
            addMessage("hostname.CannotDecodePunycode");
            throw new ValidatorException(messages);
        }

        int lengthd = decoded.size();
        int lengthe = encoded.length();

        // decoding
        boolean init = true;
        int base = 72;
        int index = 0;
        int ch = 0x80;

        int indexeStart = (separator == 1) ? (separator + 1) : 0;
        for (int indexe = indexeStart; indexe < lengthe; ++lengthd) {
            int oldIndex = index;
            int pos = 1;
            for (int key = 36; true; key += 36) {
                int hex = (int) encoded.charAt(indexe++);
                int digit = (hex - 48 < 10) ? hex - 22
                        : ((hex - 65 < 26) ? hex - 65
                        : ((hex - 97 < 26) ? hex - 97
                        : 36));

                index += digit * pos;
                int tag = (key <= base) ? 1 : ((key >= base + 26) ? 26 : (key - base));
                if (digit < tag) {
                    break;
                }
                pos = (int) (pos * (36 - tag));
            }
            int delta = (int) (init ? ((index - oldIndex) / 700) : ((index - oldIndex) / 2));
            delta += (int) (delta / (lengthd + 1));
            int key;
            for (key = 0; delta > 910; key += 36) {
                delta = (int) (delta / 35);
            }
            base = (int) (key + 36 * delta / (delta + 38));
            init = false;
            ch += (int) (index / (lengthd + 1));
            index %= (lengthd + 1);
            if (lengthd > 0) {
                for (int i = lengthd; i > index; i--) {
                    decoded.set(i, decoded.get(i - 1));
                }
            }

            decoded.set(index++, ch);
        }

        // convert decoded ucs4 to utf8 string
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < decoded.size(); i++) {
            int value = decoded.get(i);
            if (value < 128) {
                sb.append((char) value);
            } else if (value < (1 << 11)) {
                sb.append((char) (192 + (value >> 6)));
                sb.append((char) (128 + (value & 63)));
            } else if (value < (1 << 16)) {
                sb.append((char) (224 + (value >> 12)));
                sb.append((char) (128 + ((value >> 6) & 63)));
                sb.append((char) (128 + (value & 63)));
            } else if (value < (1 << 21)) {
                sb.append((char) (240 + (value >> 18)));
                sb.append((char) (128 + ((value >> 12) & 63)));
                sb.append((char) (128 + ((value >> 6) & 63)));
                sb.append((char) (128 + (value & 63)));
            } else {
                addMessage("hostname.CannotDecodePunycode");
                throw new ValidatorException(messages);
            }
        }

        return sb.toString();

    }

    /**
     * Eliminates empty values from input array
     * @param data
     * @return 
     */
    private String[] verifyArray(String[] data) {
        List<String> result = new ArrayList<String>();
        for (String s : data) {
            if (!s.equals("")) {
                result.add(s);
            }
        }

        return result.toArray(new String[result.size()]);
    }
}

Und eine validIDNs.xml mit Regex-Mustern für die verschiedenen Tlds (zu groß um sie einzuschließen :)

<idnlist>
    <idn>
        <tld>AC</tld>
        <pattern>^[\u002d0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$</pattern>
    </idn>
    <idn>
        <tld>AR</tld>
        <pattern>^[\u002d0-9a-zà-ãç-êìíñ-õü]{1,63}$</pattern>
    </idn>
    <idn>
        <tld>AS</tld>
        <pattern>/^[\u002d0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$</pattern>
    </idn>
    <idn>
        <tld>AT</tld>
        <pattern>/^[\u002d0-9a-zà-öø-ÿœšž]{1,63}$</pattern>
    </idn>
    <idn>
        <tld>BIZ</tld>
        <pattern>^[\u002d0-9a-zäåæéöøü]{1,63}$</pattern>
        <pattern>^[\u002d0-9a-záéíñóúü]{1,63}$</pattern>
        <pattern>^[\u002d0-9a-záéíóöúüőű]{1,63}$</pattern>
    </id>
</idlist>



Obwohl es viele Alternativen zu Apache-Commons gibt, sind ihre Implementierungen bestenfalls rudimentär (wie die Apache-Commons-Implementierung selbst) und in anderen Fällen sogar falsch.

Ich würde mich auch von sogenannten einfachen, nicht einschränkenden Regexen fernhalten; Das gibt es nicht. Zum Beispiel ist @ je nach Kontext mehrmals erlaubt , woher wissen Sie, dass die erforderliche vorhanden ist? Einfache Regex wird es nicht verstehen, obwohl die E-Mail gültig sein sollte. Alles Komplexere wird error-prone oder enthält sogar versteckte Performance-Killer . Wie werden Sie so etwas beibehalten?

The only comprehensive RFC compliant regex based validator I'm aware of is email-rfc2822-validator with its 'refined' regex appropriately named Dragons.java . It supports only the older RFC-2822 spec though, although appropriate enough for modern needs (RFC-5322 updates it in areas already out of scope for daily use cases).

But really what you want is a lexer that properly parses a string and breaks it up into the component structure according to the RFC grammar. EmailValidator4J seems promising in that regard, but is still young and limited.

Another option you have is using a webservice such as Mailgun's battle-tested validation webservice or Mailboxlayer API (just took the first Google results). It is not strictly RFC compliant, but works well enough for modern needs.




Wie der Name selbst andeutet, spiegelt er wider, was er zum Beispiel für die Klassenmethode usw. enthält, abgesehen von der Bereitstellung einer Funktion zum dynamischen Aufrufen einer Methode, die zur Laufzeit eine Instanz dynamisch erzeugt.

Es wird von vielen Frameworks und Anwendungen unter dem Holz verwendet, um Dienste aufzurufen, ohne den Code tatsächlich zu kennen.





validation email apache-commons java