Wonderful problems on codewars (2)

Time:2021-3-24

After work, I looked at a problem on codeworks. The topic is as follows

Write a regular, verify the password, ensure the following points,
0. The number of digits is more than six
1. It must contain lowercase letters
2. It must contain capital letters
3. Must contain numbers

Well, I haven’t worked it out for a long time. Do you know how to solve it?


I refer to Google and use a regular expression like this

function validate(password) {
  return /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{6,}$/.test(password);
}

Here are a few basic knowledge points, let me explain
The main body of regularity is this

/^[a-zA-Z0-9]{6,}$/

^,$It means from the beginning to the end. The quantifier indicates more than six times from the beginning to the end. The matching content is case and number

Besides the subject, three forward assertions are used
Let’s take a look at the application of forward assertion

‘windows (? = 95|98|nt|2000)’ matches’ windows’ in ‘Windows 2000’, but does not match ‘windows’
“Windows” in “3.1”

The main body is still matched by the main body, and the forward assertion is equivalent to a filter condition
Therefore, what we are matching here are more than six characters in the main body, only three conditions are added
What are the three conditions?

(?=.*\d)(?=.*[a-z])(?=.*[A-Z])

.*Any character appears 0 or more times, followed by a number, which means that only numbers are needed, regardless of whether there are any characters in front of it or not, or how many arbitrary characters there are.
In the same way, the lowercase and upper case after it.
And these three assertions are equivalent to the relationship of “union”.

Let’s put it together to see if we can understand it better?
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{6,}$

This sentence means that we should have more than 6 characters from the beginning to the end. There are three conditions for them. They have numbers, lowercase and uppercase

The above is the solution of ordinary youth


The answer from cheating is also quite successful. I think there will be no other answers to this kind of question, but the imagination of the person answering the question once again exceeds my imagination. Here are several other answers for expanding my thinking

function validate(password) {
  return  /^[A-Za-z0-9]{6,}$/.test(password) &&
          /[A-Z]+/           .test(password) &&
          /[a-z]+/           .test(password) &&
          /[0-9]+/           .test(password) ;
}

Four regular verifications are carried out and connected with & & to avoid the assertion inside the regular, which is the solution of literary youth

Now there are pencil solutions. Let’s take a look

function validate(password) {

  // 1) if the first char is [0-9]:
  //    a) verify what follows contains at least 1 [a-z]
  //    b) verify what follows contains at least 1 [A-Z]
  //    c) verify what follows contains only [0-9a-zA-Z] and at least 5 of them
  // 2) if the first char is [a-z]:
  //    a) verify what follows contains at least 1 [0-9]
  //    b) verify what follows contains at least 1 [A-Z]
  //    c) verify what follows contains only [0-9a-zA-Z] and at least 5 of them
  // 3) if the first char is [A-Z]:
  //    a) verify what follows contains at least 1 [a-z]
  //    b) verify what follows contains at least 1 [0-9]
  //    c) verify what follows contains only [0-9a-zA-Z] and at least 5 of them

  return /^(([0-9](?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z]))([0-9a-zA-z]{5,})|([a-z](?=[^0-9]*[0-9])(?=[^A-Z]*[A-Z]))([0-9a-zA-z]{5,})|([A-Z](?=[^a-z]*[a-z])(?=[^0-9]*[0-9]))([0-9a-zA-z]{5,}))$/.test(password);
}