drak2000
drak2000

Reputation: 19

Regex check repeating characters

I need to do a check for a 5-digit number using regex. Check condition: 1. There should be no more than 2 repeating digits (type 11234). 2. There should be no sequence 12345 or 54321. I am trying to do this: var PASSWORD_PATTERN = "^(?=[\\\\D]*\\\\d)(?!.*(\\\\d)\\\\1)(?!.*\\\\2{3,}){5,}.*$", But checking for 12345 or 54321 doesn't work.

Upvotes: 0

Views: 128

Answers (1)

The fourth bird
The fourth bird

Reputation: 163287

You can assert for not 3 of the same digits, and assert not 12345 and 54321.

Note to double escape the backslash in Java \\d.

^(?!\d*(\d)\d*\1\d*\1)(?!12345)(?!54321)\d{5}$

The pattern matches:

  • ^ Start of string
  • (?!\d*(\d)\d*\1\d*\1) Negative lookahead, do not match 3 times the same digits using 2 backreferences \1
  • (?!12345) Assert not 12345
  • (?!54321) Assert not 54322
  • \d{5} Match 5 digits
  • $ End of string

Regex demo

Or fail the match immediately, if the string does not consists of 5 digits, and match 1+ digits if all the assertions succeed.

^(?=\d{5}$)(?!\d*(\d)\d*\1\d*\1)(?!12345)(?!54321)\d+$

Regex demo

If you don't want to match ascending and descending sequences for digits 0-9, you might either manually check the string for each hardcoded sequence, or generate the sequences and add them to a list.

Then you can check if the sequence of 5 digits is in the list, and remove the exact check with the lookarounds from the pattern.

List<String> sequences = new ArrayList<>();
for (int i = 0; i < 10; i++) {
    StringBuilder sequence = new StringBuilder();
    int last = i;
    for (int j = 0; j < 5; j++) {
        ++last;
        if (last > 9) last = 0;
        sequence.append(last);
    }
    sequences.add(sequence.toString());
    sequences.add(sequence.reverse().toString());
}

String[] strings = {"12345", "54321", "34567", "90123", "112341", "12356", "00132"};

for (String s : strings) {
    if ((!sequences.contains(s)) && s.matches("^(?=\\d{5}$)(?!\\d*(\\d)\\d*\\1\\d*\\1)\\d+$")) {
        System.out.printf("%s is not a sequence and does not contain 3 of the same digits\n", s);
    }
}

Output

12356 is not a sequence and does not contain 3 of the same digits
00132 is not a sequence and does not contain 3 of the same digits

Java demo

Upvotes: 4

Related Questions