Нет повторяющейся последовательности в SSN (например, 123-12-3123)

#regex #regex-negation

#регулярное выражение #регулярное выражение-отрицание

Вопрос:

Как бы вы исключили повторяющуюся последовательность для SSN с помощью regex?

Например, следующие значения были бы запрещены:

     123-12-3123
    456-45-6456
    789-78-9789
  

Обновить

Что представляет собой повторение? * Учитывается ли * 121-233-4444?

Хороший вопрос, но нет; по крайней мере, пока. Я — обезьяна-кодировщик, заполняющий запрос от A amp; D, который, в свою очередь, выполняет запрос от клиента.

Они специально просят исправить, чтобы пользователи не могли вводить последовательность из 3 чисел, повторяющихся 3 раза. Наиболее распространенными будут те, которые перечислены выше.

Какой язык вы используете?

javascript

Кроме того, я добавляю это регулярное выражение к существующему РЕГУЛЯРНОМУ выражению, которое скрыто глубоко в приложении корпоративного уровня с тысячами пользователей. Добавление кода возможно, но совсем не желательно.

Комментарии:

1. Что означает повторение? 121-233-4444 Считается?

2. Какой язык вы используете? Разные языки имеют разные механизмы регулярных выражений…

3. Это может исключить действительные SSN, особенно с введением «рандомизации» SSN: socialsecurity.gov/employer/randomization.html

4. SSN (американский, я полагаю) не включает контрольную сумму? Как вы обнаруживаете ошибки ввода данных?

5. @Wayne Conrad, Отличная мысль, но это будет более долгосрочное изменение для приложения.

Ответ №1:

Ваш вопрос не ясен. Я предполагаю, что вы хотите, xyz-xy-zxyz где x 1 = y и y 1 = z .

Хорошего ответа нет.

Грубая сила:

 /
   ^
   (?: 012-01-2012
   |   123-12-3123
   |   234-23-4234
   |   345-34-5345
   |   456-45-6456
   |   567-56-7567
   |   678-67-8678
   |   789-78-9789
   )
   z
/x
  

Вышеуказанное может быть построено динамически:

 my @alts;
for (0..7) {
   my ($x, $y, $z) = ($_ 0, $_ 1, $_ 2);
   push @alts, "$x$y$z-$x$y-$z$x$y$z";
}

my $alt = join('|', @alts);

/^(?:$alt)z/
  

Нет необходимости проверять, поэтому можно использовать:

 /
   ^
   (?: 01-?2-? | 12-?3-? | 23-?4-? | 34-?5-?
   |   45-?6-? | 56-?7-? | 67-?8-? | 78-?9-?
   ){3}
   z
/x
  

Если в вашем языке программирования есть возможность встраивания кода:

 /
   ^
   ( [0-7] )
   ( (??{ $1 1 }) )
   ( (??{ $1 2 }) )
   -
   1 2
   -
   3 1 2 3
   z
/x
  

Вы могли бы расширить свою сеть:

 /
   ^
   ( [0-9] )( [0-9] )( [0-9] )
   -
   1 2
   -
   3 1 2 3
   z
/x
  

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

 /
   ^
   ( [0-7] )
   ( [1-8] )
   ( [1-9] )
   -
   1 2
   -
   3 1 2 3
   z
/x amp;amp; $2 == $1 1 amp;amp; $3 == $2 1
  

И затем есть это:

 s/-//g;
/
   ^
   (?: 012 | 123 | 234 | 345
   |   456 | 567 | 678 | 789
   ){3}
   z
/x
  

Для простоты я настоятельно рекомендую вам удалить не цифры перед выполнением проверки.

 /^[0-9]{3}-[0-9]{2}-[0-9]{4}z/
   or die;

s/-//g;

... check here...
  

Комментарии:

1. Отличное разнообразие опций. Я ставлю на пятое.

Ответ №2:

Сначала удалите не цифры:

 $ssn =~ s/D //g;
  

Затем проверьте, не повторяются ли группы из трех цифр:

 if ($ssn =~ /(d{3})11/) {
  print "ssn has repeating digits: $1n";
}