What's wrong with my regex or statement in cycle? I need 8-chars combination with one digit, one letter in upper case and one in lower case minimum. But I get a non-stop cycle.
public static ByteArrayOutputStream getPassword() throws IOException{
char[] chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
Random random = new Random();
String out = "";
ByteArrayOutputStream stream = new ByteArrayOutputStream();;
while (!out.matches("[0-9]+$") | !out.matches("[a-z]+$") | !out.matches("[A-Z]+$")) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 8; i++) {
char c = chars[random.nextInt(chars.length)];
sb.append(c);
}
out = sb.toString();
}
stream.write(out.getBytes());
return stream;
}
The problem is Java's matches()
must match the whole string to return true
, so your loop condition will always be true (the input can't both all digits and all letters).
There are two ways to fix your problem:
1) Add .*
to each end of you regexes:
if (!out.matches(".*[0-9].*") | !out.matches(".*[a-z].*") | !out.matches(".*[A-Z].*"))
2) Use one, albeit more complex, regex:
if (!out.matches("(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8}"))
The last option also checks that the length is 8.
Also note that you don't need ^
or $
with matches()
- they are implied by the contract.