Regex для проверки повторяющейся цифры - PullRequest
4 голосов
/ 05 января 2012

У меня есть приложение Java, в котором пользователи должны указывать ПИН-код для входа в систему. При создании ПИН существует только 3 требования:

  • Должно быть 6 цифр:

    \\d{6}
    
  • Не должно иметь 4 или более последовательных чисел:

    \\d*(0123|1234|2345|3456|4567|5678|6789)\\d*
    
  • Не должно иметь цифру, повторяющуюся 3 или более раз (например, 000957 или 623334 или 514888): Вот где я застрял ...

Я пытался:

\\d*(\\d)\\1{3}\\d*

, но я считаю, что \1 смотрит на начальное совпадение с \d* не второе совпадение с (\d).


Используемый ответ: Я обновил до использования:
\\d{6}
(0123|1234|2345|3456|4567|5678|6789|9876|8765|7654|6543|5432|4321|3210)
\\d*?(\\d)\\1{2,}\\d*

Для удовлетворения первоначально заявленных требований плюс несколько, которые у меня не было 'не думал о!Спасибо за помощь

Ответы [ 5 ]

8 голосов
/ 05 января 2012

Ваше регулярное выражение немного отключено, поскольку первое \ d будет соответствовать первому числу. После этого вы захотите сопоставить еще 2.

\\d*(\\d)\\1{2}\\d*

должен сделать трюк.

Быстрое редактирование: Если вы хотите сопоставить 2 или более числа в последовательности, просто добавьте запятую к вашему счету, не задавая максимальное число:

\\d*(\\d)\\1{2,}\\d*

Или, по крайней мере, это работает в Perl. Дайте нам знать, как вы идете.

4 голосов
/ 05 января 2012

Хотите ли вы заблокировать три повторяющихся следующих числа или просто более трех чисел в целом (например, в «112213»)?

Если это последний случай, Regex может быть не лучшим решениемк проблеме:

public static boolean validate(String pin){
    if (pin == null || pin.length() != 6)
        return false;

    int[] count = new int[10];
    for (int i = 0; i < pin.length(); i++) {
        char c = pin.charAt(i);
        if(!Character.isDigit(c))
            return false;

        if (++count[c - '0'] > 3)
            return false;
    }

    return true;
}
1 голос
/ 05 января 2012

Похоже, вы проводите три отдельных матча с регулярным выражением, предположительно сводя на нет результаты второго и третьего.В этом случае это должно сработать:

pinString.matches("^\\d{6}$")

!pinString.matches("^.*?(?:0123|1234|2345|3456|4567|5678|6789).*$")

!pinString.matches("^.*?(\\d)\\1{2}.*$")

С помощью метода matches() вам на самом деле не нужны якоря (^ и $), но они не повреждают иони делают ваши намерения более очевидными.Кроме того, первое регулярное выражение гарантирует, что все шесть символов являются цифрами, поэтому можно безопасно использовать . вместо \\d в качестве заполнителя пробела в двух других.

1 голос
/ 05 января 2012

Я бы:

  1. Проверка длины == 6
  2. Проверка \ d +
  3. Частота подсчета каждой цифры:

</p> <pre><code>int[] f = new int[10]; int pow10 = 1; int npow10 = 10; int nmod = 0, nmod2 = n % 10; while(i < 6) do int iDigit = (nmod2 - nmod)/pow10 if(++f[iDigit] > 2) return false; pow10 = npow10; npow10 *= 10; nmod = nmod2; nmod2 = n % npow10; i++; end return true;

0 голосов
/ 05 января 2012

Ну ваши примеры и ваш текст не совпадают.Вы говорите, что это не может повториться более 3 раз.000 - это повторение ровно 3 раза, поэтому все должно быть в порядке, но 0000 - это повторение 4, что больше 3, поэтому не должно быть.Чтобы соответствовать вашему текстовому требованию, ваше регулярное выражение должно быть

.*(\d)\1{3}.*

Что в строке Java должно быть

".*(\\d)\\1{3}.*"

Это похоже на то, что у вас есть, поэтому, возможно, вы просто неправильноформулировка.

Примечание: мне нравится проверять мое регулярное выражение в Java: http://www.regexplanet.com/simple/index.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...