0

I am trying to create a small program that reads a password and determines if it is a password you can use. I was using matches() to see if it has at least one letter (uppercase or lowercase) and one digit as well as be 6 characters long. I try to use matches like this:

if ( passwordLength >= 6 
   && password.matches("[A-Za-z]") 
   && password.matches("\\d")
) {
    System.out.println("Valid Password.");
} 
else {
    System.out.println("Invalid Password.");
}

Im not sure what i am doing wrong. Please help.

Hunter McMillen
  • 59,865
  • 24
  • 119
  • 170

3 Answers3

1

matches function should try to match the whole string using the regex we gave. So instead of using two or more matches functions for condition checking, you may use a single one with a complex regex. And also it seems like your password would contain not only digits or letters but also some other characters too.

string.matches("^(?=.*[a-zA-Z])(?=.*\\d).{6,}$");
  • (?=.*[a-zA-Z]) Positive lookahead which asserts that the string going to be matched must contain atleast one letter.

  • (?=.*\\d) asserts it must contain atleast one digit.

  • .{6,} ensures that the length must be atleast 6 and atmost any..

For the length to be exactly 6 then change .{6,} in the above to .{6}

DEMO

Avinash Raj
  • 172,303
  • 28
  • 230
  • 274
  • This doesnt explain what was wrong with the initial approach or how this solution solves the problem – Hunter McMillen Nov 05 '15 at 00:34
  • I'm with @HunterMcMillen. While this is a fine solution, the "teach a person to fish" mindset suggests it would be good to explain why the original doesn't work. – blm Nov 05 '15 at 00:37
0

There are a couple of things wrong with your code:

  • Your regex is wrong. You are only matching on 1 character, so you should change the [a-z] to [a-z]+.
  • You are matching on 'it should be bigger than 6, should be a character, AND it should be a number. That's different from your requirement.
Erik Pragt
  • 13,513
  • 11
  • 58
  • 64
  • for the second part, he must need to use contains. Since `\\d+` checks for the string to contain digits only. – Avinash Raj Nov 05 '15 at 00:29
  • Maybe, but checking if a password is either only digits or only characters is a bit weird, right? Probably `^[a-zA-Z0-9]{6,}$` would make more sense in this example. – Erik Pragt Nov 05 '15 at 00:30
  • no, he wants the password to contain atleast one digit and atleast one letter. – Avinash Raj Nov 05 '15 at 00:31
  • That's basically completely wrong. The fundamental problem is that `matches()` matches the entire string, so `password.matches("[A-Za-z]")` only returns true if password is one character long and that character is an upper- or lowercase ASCII letter. On the the second bullet point, no it's not weird, because the poster want passwords to be at least 6 characters long AND contain a letter AND contain a digit. The poster's just doing the contains part wrong. – blm Nov 05 '15 at 00:31
  • Ah, sorry, I missed that completely, I was only looking at the code. – Erik Pragt Nov 05 '15 at 00:33
0

It looks like you're misinterpreting the matches function, which matches over the entire input, while you're expecting it to return true if a substring matches. As others suggested, you'll need to use a single regex and matches() call since you're asking if the string is a single character AND a number (which would never be true).

Another important point, though it may not be important to you, is that a password should never be stored as a String object since they're immutable and can persist long enough for something else to come along and read it. More on that here.

Matt O
  • 1,336
  • 2
  • 10
  • 19