Username cannot contain duplicate underscore or period

I have always struggled with these traits. I remember how the lecturer told us about everything, that if you have a problem requiring the use of regular expressions to solve it, you actually have 2 problems.

Well, of course, I agree with that. Regex is something that we don’t use very often, but when we do it, like reading some foreign language (well, for me it’s all the same) ... I think I’ll let me get the book and read on.

I have a problem: I need to check the username based on the following criteria:

  • may contain letters, upper and lower
  • may contain numbers
  • may contain periods ( . ) and underscores ( _ )
  • periods and underscores cannot be consecutive, i.e. __ .. not allowed, but ._._ will be valid.
  • no more than 20 characters

So far I have had the following: ^[a-zA-Z_.]{0,20}$ , but of course this allows you to repeat underscores and periods.

Now I'm probably starting all this wrong with a set of valid characters and maximum length. I tried (unsuccessfully) to create some kind of look or look or something else to look for invalid period repetitions ( . ) And underscores ( _ ), not sure what approach or methodology to eliminate this requirement in regex.

Can someone help with a recommendation / alternative approach or point me in the right direction?

+6
source share
3 answers

This is the one you need:

 ^(?:[a-zA-Z0-9]|([._])(?!\1)){5,20}$ 

Regular expression visualization

Change live in Debuggex

You may have a demonstration that it matches here .


"Either the alphabet char ( [a-zA-Z0-9] ), or ( | ) a period or underscore ( [._] ), but that does not follow ( (?!\1) ), but from From 5 up to 20 times ( {5,20} ).

  • (?:X) simply not an exciting group, i.e. you cannot reference it after using the syntax \1 , $1 or ?1 .

  • (?!X) is called a negative look, that is literally "which does not follow X".

  • \1 refers to the first capture group. Since the first group (?:...){5,20} was set as not exciting (see # 1), the first group of capture ([._]) .

  • {X,Y} means X to Y times, you can change it as you need.

+8
source

To do this, you can use two negative statements to view :

 ^(?!.*__)(?!.*\.\.)[0-9a-zA-Z_.]{0,20}$ 

Explanation:

 (?! # Assert that it impossible to match the following regex here: .* # Any number of characters __ # followed by two underscores in a row ) # End of lookahead 

Depending on your requirements and your regular expression engine, you can replace [0-9A-Za-z_.] [\w.] .

@ sp00n raised a good point: you can combine lookahead statements in one:

 ^(?!.*(?:__|\.\.))[0-9a-zA-Z_.]{0,20}$ 

which may be a little more efficient, but a little harder to read.

+6
source

Do not try to insert this into one regex. Your only regular expression works fine for all criteria except # 4. To do # 4, just enter a regular expression that matches invalid usernames and reject the username if it matches. For example (in pseudo-code):

 if username.matches("^[a-zA-Z_.]{0,20}$") and !username.matches("__|\\.\\.") { /* accept username */ } 
+6
source

Source: https://habr.com/ru/post/950958/


All Articles