1

There are lot of similar questions on the Regex, however I am still confused on the following case:

import java.util.regex.Pattern;

public class PatternTest {

  public static void main(String[] args) {
    String PATTERN = "((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{8,20})";
    Pattern pattern = Pattern.compile(PATTERN);

    boolean isTrue = pattern.matcher("nks#n1Kos2~([{&").matches();

    System.out.println(isTrue);
  }

}

The characters of ~([{& is not in the PATTERN, however the matches shows up true. What is the reason for that?

Here is a link on Java Regular Expression Tester https://www.freeformatter.com/java-regex-tester.html#ad-output

1
  • 2
    to help with confusion whet do .{8,20} match, yes ? not wise to restrict to set of characters for passwords. hackers guess that, combinations is doable Commented May 28, 2020 at 19:34

2 Answers 2

2

Your regex is:

String PATTERN = "(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%]).{8,20}";

Which means match any character of 8 to 20 in length that fulfills all the conditions given in lookahead.

What you actually need is this:

String PATTERN = "(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%])[a-zA-Z\\d@#$%]{8,20}";

[a-zA-Z\\d@#$%]{8,20} will match only allowed characters inside [...] 8 to 20 in length.

Sign up to request clarification or add additional context in comments.

1 Comment

[a-zA-Z\\d@#$%] works, however it's kind of clumsy for it needs to list all of the characters once more.
2

The (?=X) patterns are "zero-width positive lookahead" assertions. So they're asserting that the regexes are found in the search string without consuming any of it. All of these assertions are passing successfully.

The .{8,20} pattern is saying "match any character as long as there are between 8 and 20 of them (inclusive)". So it is matching the entire string.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.