Регулярное выражение?

Рейтинг: 0Ответов: 4Опубликовано: 20.01.2023

Подскажите пожалуйста регулярное выражение. Нужно чтобы в строке обязательно было # и не меньше и не больше 4 цифр. Вот так: test#1111, вот это не правильно: test#11111

Вот моя регулярка, оно работает, но когда у меня 5 цифр, то оно все равно возвращает true Вот это работает: /#\d{4}/g.test('test#33443')

Ответы

▲ 2

Используйте утверждения. Дополните выражение тем что после четвертой цифры не должно быть пятого.

const regex = /#\d{4}(?!\d)/;
[`test#4444`, `test#55555`].forEach(text => {
  console.log(`${text} → ${regex.test(text)}`);
});


Момент

Осторожно с флагом g. Повторное использование одного выражения с флагом g может резко менять результат:

const regex = /#\d{4}(?!\d)/g;
[`test#1234`, `test#2341`, `test#3412`, `test#4123`].forEach(text => {
  console.log(`${text} → ${regex.test(text)}`);
});

Почему так происходит, ответили тут.

▲ 1

Про регулярные выражения важно понять одну вещь: если паттерну соответствует любая часть строки, совпадение засчитывается.

Поэтому паттерн /123/ будет соответствовать любой строке, где есть цифры 1, 2 и 3 — в начале, середине или конце: 123abc, 123, 12345, 01234, -123.

Поэтому важно задавать ограничения. Чаще всего паттерну должен удовлетворять текст в начале строки, тогда в начале паттерна ставят "крышку" ^.

/^123/ будет соответствовать любой строке, которая начинается с 123.

Точно также /123$/ будет соответствовать любой строке, которая заканчивается на 123.

Если бы вы хотели, чтобы строка состояла из # и четырёх цифр, вам подошёл бы паттерн /^#\d\d\d\d$/ или /^#\d{4}$/. ^ в начале и $ в конце указывают, что строка должна соответствовать паттерну целиком.

Но в вашем случае ограничения должны быть более тонкими. Паттерну должна удовлетворять часть строки, но есть дополнительное условие: сразу за ним не должно быть цифры. У нас по сути получается два паттерна. Сначала мы находим часть строки, которая соответствует первому паттерну, а потом заглядываем вперёд (look ahead) и убеждаемся, что оставшаяся часть строки соответствует второму.

Второй паттерн надо указать сразу после первого в скобках (?=) или (?!).

/#\d{4}(?!\d)/ означает "после проверки паттерна #\d{4} заглянуть дальше и убедиться, что там не цифра". Это — негативная проверка.

(?=) это позитивная проверка, то есть мы убеждается, что за первым паттерном точно следует второй. Утверждение не цифра мы можем выразить и так, но выражение будет сложнее /#\d{4}(?=[^\d])/. Мы помним, что [^\d] соответствует любому символу, который не является цифрой.

▲ 0

Нужно чтобы в строке обязательно было # и не меньше и не больше 4 цифр. Вот так: test#1111, вот это не правильно: test#11111

Предложу такой вариант...

console.log(/#\d{4}(?=[^\d]|$)/g.test('test#33443'))
console.log(/#\d{4}(?=[^\d]|$)/g.test('test#3344'))

▲ 0

Предложу свой вариант без lookahead assertion и negative lookahead assertion

Регулярка:

  1. # - искомая строка должна начинаться с этого знака

  2. \d - любая цифра. \d{4} - подряд 4 цифры

  3. [^\d] - любой символ кроме цифры

  4. $ - конец строки

  5. | - оператор или. [^\d]|$ - или не цифра или конец строки

const regex = /#\d{4}([^\d]|$)/;

[
  'test#123',
  'test#1234',
  'test#12345',
  'test#1234 5',
  'test#1234end',
].forEach(text => console.log(text, regex.test(text)));

По постановке задачи, не вижу смысла использовать lookahead assertion или negative lookahead assertion т.к. допустимым символом после 4-х цифр - это просто либо не цифра либо же конец строки