Regular expression to validate username

Viewed 148828

I'm trying to create a regular expression to validate usernames against these criteria:

  1. Only contains alphanumeric characters, underscore and dot.
  2. Underscore and dot can't be at the end or start of a username (e.g _username / username_ / .username / username.).
  3. Underscore and dot can't be next to each other (e.g user_.name).
  4. Underscore or dot can't be used multiple times in a row (e.g user__name / user..name).
  5. Number of characters must be between 8 to 20.

This is what I've done so far; it sounds it enforces all criteria rules but the 5th rule. I don't know how to add the 5th rule to this:

 ^[a-zA-Z0-9]+([._]?[a-zA-Z0-9]+)*$
12 Answers
private static final Scanner scan = new Scanner(System.in);

public static void main(String[] args) {
    int n = Integer.parseInt(scan.nextLine());
    while (n-- != 0) {
        String userName = scan.nextLine();
        String regularExpression = "^[[A-Z]|[a-z]][[A-Z]|[a-z]|\\d|[_]]{7,29}$";
        if (userName.matches(regularExpression)) {
            System.out.println("Valid");
        } else {
            System.out.println("Invalid");
        }
    }
}
^(?=.{4,20}$)(?:[a-zA-Z\d]+(?:(?:\.|-|_)[a-zA-Z\d])*)+$

You can test the regex here

const regex = /^moe_(app|lab)[A-Za-z0-9]{3}$/;
const str = `moe_app_baa`;
let m;

if ((m = regex.exec(str)) !== null) {
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Stumbled upon this question in another one. Seems not necessary to use that many lookarounds. Following a bit shorter pattern with use of \w which is a short for word character and commonly preset to [A-Za-z0-9_]. To get rid of the underscore, [^\W_] can be used to match [A-Za-z0-9].

^[^\W_](?!.*?[._]{2})[\w.]{6,18}[^\W_]$
  • ^[^\W_] one letter or digit at the start
  • (?!.*?[._]{2}) negative lookahead to disallow __ ._ _. ..
    (for reduing steps on longer inputs, a lazy quantifier is used in .*?)
  • [\w.]{6,18} 6 to 18 characters that can be letters, digits, _ and .
  • [^\W_]$ ending in another letter or digit

See this demo at regex101 (further explanation on the right side)

Note: \w depending on environment/settings can further contain unicode letters and digits.

function isUserName(val){
    let regUser=/^[a-zA-Z0-9](_(?!(\.|_))|\.(?!(_|\.))|[a-zA-Z0-9]){6,18}[a-zA-Z0-9]$/;
    if(!regUser.test(val)){
      return 'Name can only use letters,numbers, minimum length is 8 characters';
    }
  }
Related