Что не так в моем регулярном выражении /(?= ^[a-z] d{2,})(?=w{5,})/ pattern?

#javascript #regex #positive-lookahead

#javascript #регулярное выражение #позитивный взгляд

Вопрос:

Это регулярное выражение должно соответствовать паролям длиной более 5 символов, не начинающимся с цифр и состоящим из двух последовательных цифр.

Все тестовые примеры проходят тест регулярных выражений.

Мое регулярное выражение /(?=^[a-z] d{2,})(?=w{5,})/

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

Но astr1on11aut не проходит тест. Почему?

Ссылка на проблему- https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/regular-expressions/positive-and-negative-lookahead

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

1. regex101.com/r/JnWV5J/1

2. Это не удается, потому что «astr1on11aut» начинается с букв (совпадающих ^[a-z] ), а затем имеет одну цифру, которая не соответствует вашему ограничению d{2,} . Следовательно, тест на (?=^[a-z] d{2,}) сбой.

Ответ №1:

Ваше регулярное выражение завершается ошибкой из-за первого шаблона (?=^[a-z] d{2,}) поиска. Строка «astr1on11aut» начинается со строчных букв:

 astr1on11aut
^^^^
  

Это соответствует ^[a-z] . Однако следующая часть шаблона требует двух или более цифр с d{2,} , однако строка содержит только одну в этом месте:

    astr1on11aut
       ^^
       ||
digit - |
          --- not a digit
  

Это приводит к сбою первого шаблона поиска.

Вы можете более четко выразить правила проверки с помощью трех предпросмотров:

  • «длина более 5 символов: (?=.{5,})
  • «не начинайте с чисел»: ^(?!d)
  • «и имеют две последовательные цифры»: (?=.*d{2})

Если мы соберем их все вместе, получим /(?=.{5,})(?!^d)(?=.*d{2})/

 const regex = /^(?=.{5,})(?!d)(?=.*d{2})/;

test("abc");
test("123");
test("123abc");

test("abc123");
test("astr1on11aut");

test("., ;_'@=-%");
test("., ;_'@123=-%");

function test(string) {
  console.log(`${string} : ${regex.test(string)}`);
}  

Обратите внимание, что это регулярное выражение не требует букв. Строго следуя требованиям, единственное, что явно запрашивается, — это цифры. Поскольку тип любого другого ввода не указан, он остается любым (используемым . ). При написании регулярного выражения лучше не делать слишком много предположений, иначе вы можете заблокировать допустимый ввод.

Ответ №2:

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

 if (input.match(/^D/)
    amp;amp; input.match(/d{2}/)
    amp;amp; input.length >= 5) {
  // password policy fulfilled
}
  

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

1. Просмотры поддерживаются всеми движками JS, о которых я знаю. Поиск сзади не поддерживается в старых.

2. Спасибо. Давайте оставим ответ еще проще: не все должно решаться как одно регулярное выражение. В большинстве случаев у вас есть основной язык, поэтому давайте используем его возможности.

3. Аминь этому. Я чувствую, что большая часть моего времени над тегом регулярных выражений тратится на попытки напомнить людям, что вам не нужно регулярное выражение для всего, что связано со строками. Однако задача OP конкретно связана с созданием регулярного выражения здесь. Я бы все равно поддержал решение, которое использует не только это, потому что мы действительно должны больше учить людей использовать строки и меньше полагаться на регулярные выражения. Это полезный инструмент, но им слишком часто злоупотребляют и неправильно применяют люди, которые на самом деле не понимают регулярных выражений, но все равно решают их использовать. Проверки электронной почты заставляют меня плакать.

Ответ №3:

Это работает для вас?

 (?=^D.{5,}$).*(?=d{2,})
  

Первый предварительный просмотр утверждает, что строка не должна начинаться с цифры, но иметь длину не менее 6 символов; второй утверждает, что должно быть не менее 2 последовательных цифр.

Ответ №4:

Это регулярное выражение проходит все тесты

 /(?=w*dd)(?=w{5,})(?=^[^0-9]w*)/
  

Я полагаю, вы могли бы исправить свое, разделив первую группу.