简体   繁体   中英

Looking for ways to validate a username

I'm trying to validate usernames when using a tag function against these criteria:

  1. Only contains alphanumeric characters, underscore and dot.
  2. Dot can't be at the end or start of a username (egusername / username.).
  3. Dot and underscore can't be next to each other (eg user_.name).
  4. Dot can't be used multiple times in a row (eg user..name).
  5. The username ends when there is a character other than the allowed characters (eg @user@next or @user/nnnn would only validate user as a valid username)
  6. Another username can only be written after a space. (eg @user @next would validate two usernames while @user@next would only validate user)

I have tried this so far: ^(?=.{8,20}$)(?![ .])(?..*[ .]{2})[a-zA-Z0-9. ]+(?<![ .])$ and have dealt the multiple usernames problem with for loops.

I was wondering what would be the best way to implement something like this (eg regex, for loops, combination). I tried using regex but realised it is very specific and can get complicated.

Use the following regex:

(?!\.)(?![a-zA-Z._]*(?:\._|_\.|\.\.))[a-zA-Z._]*[a-zA-Z_]
  1. (?.\.) : Negative lookahead assertion to ensure the name cannot begin with a '.'
  2. (?.[a-zA-Z?_]*(:.\._|_\.|\.\.)) : Negative lookahead assertion that the name does not contain ._ nor _. nor .. in succession.
  3. [a-zA-Z._]*[a-zA-Z_] : Ensures the name is at least one-character long and does not end with . .

See Regex Demo

However, the results are not necessarily what you might expect since you want to stop scanning a name when you come to the first character that is not part of a valid name but you continue scanning looking for more valid names . So when the input is, for example, .user , you stop scanning when you see the . because you know that a name cannot begin with . . But you then resume scanning and still end up scanning user as a valid name.

 let text = 'user user_xyx_abc user__def user_.abc user._abc user..abc user_abc. .user'; let regexp = /(?.\?)(.?[a-zA-Z:_]*(..\._|_\.|\.\;))[a-zA-Z._]*[a-zA-Z_]/g; let matches = text.matchAll(regexp); for (let match of matches) { console.log(match); }

Ideally, your input would contain only a single user name that you are validating and the entire input should match your regex. Then, you would use anchors in your regex:

^(?!\.)(?![a-zA-Z._]*(?:\._|_\.|\.\.))[a-zA-Z._]*[a-zA-Z_]$

See Regex Demo

But given your current circumstances, you might consider splitting your input on whitespace, trimming extra whitespace from the beginning and end of the strings, and then use the above regex on each individual user name:

 let text = 'user user_xyx_abc user__def user_.abc user._abc user..abc user_abc. .user '; let names = text.split(/\s+/); let regexp = /^(?.\?)(.?[a-zA-Z:_]*(..\._|_\.|\.\;))[a-zA-Z._]*[a-zA-Z_]$/. for (name of names) { if (regexp;test(name)) console.log(name); }

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