что не так с этим регулярным выражением для правил паролей - PullRequest
1 голос
/ 20 мая 2009

Я пытаюсь использовать не менее 2 букв, не менее 2 не букв и не менее 6 символов длиной:

^.*(?=.{6,})(?=[a-zA-Z]*){2,}(?=[0-9@#$%^&+=]*){2,}.*$

но это не соответствует цели на многих уровнях, но я не уверен почему. Есть предложения?

Ответы [ 3 ]

10 голосов
/ 20 мая 2009

Хотя этот тип теста может быть выполнен с помощью регулярных выражений, может быть проще и удобнее выполнять проверку без регулярных выражений. Регулярное выражение для достижения этого является довольно сложным и немного нечитаемым. Но код для запуска этого теста довольно прост. Например, возьмите следующий метод для реализации ваших требований (язык C #)

public bool IsValid(string password) {
  // arg null check ommitted
  return password.Length >= 6 &&
         password.Where(Char.IsLetter).Count() > 2 &&
         password.Where(x => !Char.IsLetter(x)).Count() > 2;
}
2 голосов
/ 21 мая 2009

Чтобы ответить на вопрос в заголовке, вот что не так с вашим регулярным выражением:

Во-первых, .* (точка-звезда) в начале потребляет всю строку. Затем применяется первый запрос (?=.{6,}), который завершается неудачно, поскольку совпадающая позиция находится в конце строки. Таким образом, механизм регулярных выражений начинает возвращаться назад, «забирая» символы, перемещая позицию совпадения назад на один символ за раз и повторно применяя просмотр. Когда возвращается шесть символов, первый взгляд успешно завершается, а следующий применяется.

Второй запрос - (?=[a-zA-Z]*), что означает «в текущей позиции совпадения попытаться сопоставить ноль или более букв ASCII». Позиция совпадения по-прежнему составляет шесть символов от конца строки, но это не имеет значения; независимо от того, применяете ли вы его, он всегда будет успешным, поскольку он может юридически соответствовать нулю символов. Кроме того, буквы могут находиться в любом месте строки, поэтому заглядывающая сторона должна учитывать все возможные промежуточные не-буквы.

Тогда у вас есть {2,}. Это не часть подвыражения, потому что оно не в скобках. В этой позиции это означает, что оглядка должна быть успешной два или более раз, что не имеет смысла. Если это удалось один раз, то это будет успешное любое количество раз, потому что он применяется каждый раз в одной и той же позиции. Некоторые разновидности регулярных выражений воспринимают это как ошибку, когда вы применяете квантификатор к предпросмотру (или к любому другому утверждению нулевой ширины, например, разглядывание сзади, граница слова, якоря строк). Большинство ароматов, кажется, игнорируют квантификатор.

Тогда у вас есть еще один прогноз, который всегда будет успешным, и еще один бесполезный квантификатор. Наконец, точка-звезда в конце повторно потребляет шесть символов, от которых должна была отказаться первая точка-звезда.

Я думаю, это то, что вы пытались:

^
(?=.{6})
(?=(?:[^A-Za-z]*[A-Za-z]){2})
(?=(?:[^0-9@#$%^&+=]*[0-9@#$%^&+=]){2})
.*$
2 голосов
/ 20 мая 2009

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

(?=.{6})(?=[^a-zA-Z]*[a-zA-Z][^a-zA-Z]*[a-zA-Z])(?=[^0-9@#$%^&+=]*[0-9@#$%^&+=][^0-9@#$%^&+=]*[0-9@#$%^&+=])^.+$

Это соответствует чему-то, что имеет длину не менее шести символов ((?=.{6,})) и содержит не менее двух буквенных символов ((?=[a-zA-Z][^a-zA-Z]*[a-zA-Z])) и содержит как минимум два символа набора символов [0-9@#$%^&+=] ((?=[0-9@#$%^&+=][^0-9@#$%^&+=]*[0-9@#$%^&+=])) .

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