简体   繁体   中英

Regular expression to validate username

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 (eg _username / username_ / .username / username. ).
  3. Underscore and dot can't be next to each other (eg user_.name ).
  4. Underscore or dot can't be used multiple times in a row (eg 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]+)*$
^(?=.{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})[^_.].*[^_.]$

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)

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.......

对菲利普的答案稍作修改修复了最新要求

^[a-zA-Z0-9]([._](?![._])|[a-zA-Z0-9]){6,18}[a-zA-Z0-9]$
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])*)+$

你可以在这里测试正则表达式

^[a-z0-9_-]{3,15}$

^ # Start of the line

[a-z0-9_-] # Match characters and symbols in the list, az, 0-9, underscore, hyphen

{3,15} # Length at least 3 characters and maximum length of 15

$ # End of the line

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

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
} 
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';
    }
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM