Regular expression to validate username
JavaPhpHtmlRegexPerlJava Problem Overview
I'm trying to create a regular expression to validate usernames against these criteria:
- Only contains alphanumeric characters, underscore and dot.
- Underscore and dot can't be at the end or
start of a username (e.g
_username
/username_
/.username
/username.
). - Underscore and dot can't be next to each other (e.g
user_.name
). - Underscore or dot can't be used multiple times in a row (e.g
user__name
/user..name
). - 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]+)*$
Java Solutions
Solution 1 - Java
^(?=.{8,20}$)(?![_.])(?!.*[_.]{2})[a-zA-Z0-9._]+(?<![_.])$
└─────┬────┘└───┬──┘└─────┬─────┘└─────┬─────┘ └───┬───┘
│ │ │ │ no _ or . at the end
│ │ │ │
│ │ │ allowed characters
│ │ │
│ │ no __ or _. or ._ or .. inside
│ │
│ no _ or . at the beginning
│
username is 8-20 characters long
If your browser raises an error due to lack of negative look-behind support, use the following alternative pattern:
^(?=[a-zA-Z0-9._]{8,20}$)(?!.*[_.]{2})[^_.].*[^_.]$
Solution 2 - Java
I guess you'd have to use Lookahead expressions here. http://www.regular-expressions.info/lookaround.html
Try
^[a-zA-Z0-9](_(?!(\.|_))|\.(?!(_|\.))|[a-zA-Z0-9]){6,18}[a-zA-Z0-9]$
[a-zA-Z0-9]
an alphanumeric THEN (
_(?!\.)
a _ not followed by a . OR
\.(?!_)
a . not followed by a _ OR
[a-zA-Z0-9]
an alphanumeric ) FOR
{6,18}
minimum 6 to maximum 18 times THEN
[a-zA-Z0-9]
an alphanumeric
(First character is alphanum, then 6 to 18 characters, last character is alphanum, 6+2=8, 18+2=20)
Solution 3 - Java
As much as I love regular expressions I think there is a limit to what is readable
So I would suggest
new Regex("^[a-z._]+$", RegexOptions.IgnoreCase).IsMatch(username) &&
!username.StartsWith(".") &&
!username.StartsWith("_") &&
!username.EndsWith(".") &&
!username.EndsWith("_") &&
!username.Contains("..") &&
!username.Contains("__") &&
!username.Contains("._") &&
!username.Contains("_.");
It's longer but it won't need the maintainer to open expresso to understand.
Sure you can comment a long regex but then who ever reads it has to rely on trust.......
Solution 4 - Java
A slight modification to Phillip's answer fixes the latest requirement
^[a-zA-Z0-9]([._](?![._])|[a-zA-Z0-9]){6,18}[a-zA-Z0-9]$
Solution 5 - Java
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");
}
}
}
Solution 6 - Java
^(?=.{4,20}$)(?:[a-zA-Z\d]+(?:(?:\.|-|_)[a-zA-Z\d])*)+$
You can test the regex here
Solution 7 - Java
^[a-z0-9_-]{3,15}$
^ # Start of the line
[a-z0-9_-] # Match characters and symbols in the list, a-z, 0-9, underscore, hyphen
{3,15} # Length at least 3 characters and maximum length of 15
$ # End of the line
Solution 8 - Java
Err sorry I generated this from my own library and it uses the syntax valid for Dart/Javascript/Java/Python, but anyway, here goes:
(?:^)(?:(?:[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKlMNOPQRSTUVWXYZ0123456789]){1,1})(?!(?:(?:(?:(?:_\.){1,1}))|(?:(?:(?:__){1,1}))|(?:(?:(?:\.\.){1,1}))))(?:(?:(?:(?:[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKlMNOPQRSTUVWXYZ0123456789._]){1,1})(?!(?:(?:(?:(?:_\.){1,1}))|(?:(?:(?:__){1,1}))|(?:(?:(?:\.\.){1,1}))))){6,18})(?:(?:[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKlMNOPQRSTUVWXYZ0123456789]){1,1})(?:$)
My library code:
var alphaNumeric = ["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", "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", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
var allValidCharacters = new List.from(alphaNumeric);
allValidCharacters.addAll([".", "_"]);
var invalidSequence = (r) => r
.eitherString("_.")
.orString("__")
.orString("..");
var regex = new RegExpBuilder()
.start()
.exactly(1).from(alphaNumeric).notBehind(invalidSequence)
.min(6).max(18).like((r) => r.exactly(1).from(allValidCharacters).notBehind(invalidSequence))
.exactly(1).from(alphaNumeric)
.end()
.getRegExp();
My library: https://github.com/thebinarysearchtree/RegExpBuilder
Solution 9 - Java
This one should do the trick:
if (Regex.IsMatch(text, @"
# Validate username with 5 constraints.
^ # Anchor to start of string.
# 1- only contains alphanumeric characters , underscore and dot.
# 2- underscore and dot can't be at the end or start of username,
# 3- underscore and dot can't come next to each other.
# 4- each time just one occurrence of underscore or dot is valid.
(?=[A-Za-z0-9]+(?:[_.][A-Za-z0-9]+)*$)
# 5- number of characters must be between 8 to 20.
[A-Za-z0-9_.]{8,20} # Apply constraint 5.
$ # Anchor to end of string.
", RegexOptions.IgnorePatternWhitespace))
{
// Successful match
} else {
// Match attempt failed
}
Solution 10 - Java
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}`);
});
}
Solution 11 - Java
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';
}
}