Simple code to check format of user inputted email address I am helping a friend with her Java homework and I adapted a solution I used in a similar project of my own for this. It is supposed to use loose/generous regex to make sure an email entered matches the forms abc123@xyz.net or abc.123@xyz.net.

import java.util.Scanner;

public class App {

    Scanner scanner;

    public App() {
        this.scanner = new Scanner(System.in);
    }

    public static void main(String[] args) {
        App app = new App();

        app.GetUsername(true);
    }

    public void GetUsername(Boolean firstRun) {

        if(!firstRun) {
            System.out.println("The username you have entered was in an incorrect format. Must match abc@xyz.net");
        } else {
            System.out.println("Please enter a username:");
        }

        String userInput = this.scanner.nextLine();

        UsernameCheck usernameCheck = new UsernameCheck(userInput);

        if(usernameCheck.isValid()) {
            System.out.println("Welcome, " + userInput + "!");
        } else {
            GetUsername(false);
        }
    }

}


UsernameCheck.java

import java.util.regex.*;

public class UsernameCheck {

    String username;

    public UsernameCheck(String username) {
        this.username = username;
    }

    public Boolean isValid() {
        return this.username.matches("[a-zA-Z0-9\\.]+@[a-zA-Z0-9\\-\\_\\.]+\\.[a-zA-Z0-9]{3}");
    }
}


I am most interested in hearing alternative solutions for re-prompting a user if the input they've given is invalid. This works in practice, but I am looking for the cleanest way to do it.
My preference for accepting user input in a blocking loop like this might look more like:

  public enum Returned { OK, ERROR_EMAIL };


…

  // Long loop here to get valid user registration info.
  /* In a transactional/event-driven (GUI, web) app this would not be
   * a loop, but with a blocking/modal (tty) program it works. */

  UserInfo u = new UserInfo ();
  // loop until you get valid one(s)
  while (!u.isReady()) {

    // for each field that must be validated, prompt and try to set it
    if (u.getName () == null) {
        System.out.print ("Enter an eMail address:");
        String entered = scanner.nextLine ();

        Returned settingName = u.setName (entered);

        // check each object's validity and report errors
        switch (settingName) {
            case Returned.OK:
                  System.out.println ("OK.");
                  break;
            case Returned.ERROR_EMAIL:
                  System.out.println ("That does not look like a valid eMail address.");
                  break;
             // No "default": if you add new error types later, you can handle them here.
             // The compiler will issue a warning about unhandled enum cases
        }
     }
  }


…and then in class UserInfo …

  final static Pattern rfc2822 = Pattern
                            .compile ("[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&amp;'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?");

  public Returned setName (final String address)
  {
       Returned valid = isValid(address);
       if (Returned.OK == valid) { this.name = address; }
       return valid;
  }

  public boolean isValid (final String address)
  {
         return ( (rfc2822.matcher(address).matches ())
                  ? Returned.OK : Returned.ERROR_EMAIL );
         // you could also check for a valid MX record for the domain part…
  }

  public boolean isReady () {
         return name != null; // and whatever else
  }