Регулярное выражение?
Подскажите пожалуйста регулярное выражение. Нужно чтобы в строке обязательно было # и не меньше и не больше 4 цифр. Вот так: test#1111, вот это не правильно: test#11111
Вот моя регулярка, оно работает, но когда у меня 5 цифр, то оно все равно возвращает true
Вот это работает: /#\d{4}/g.test('test#33443')
Ответы (4 шт):
Нужно чтобы в строке обязательно было # и не меньше и не больше 4 цифр. Вот так: test#1111, вот это не правильно: test#11111
Предложу такой вариант...
console.log(/#\d{4}(?=[^\d]|$)/g.test('test#33443'))
console.log(/#\d{4}(?=[^\d]|$)/g.test('test#3344'))
Используйте утверждения. Дополните выражение тем что после четвертой цифры не должно быть пятого.
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)}`);
});
Почему так происходит, ответили тут.
Про регулярные выражения важно понять одну вещь: если паттерну соответствует любая часть строки, совпадение засчитывается.
Поэтому паттерн /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] соответствует любому символу, который не является цифрой.
Предложу свой вариант без lookahead assertion и negative lookahead assertion
Регулярка:
#- искомая строка должна начинаться с этого знака\d- любая цифра.\d{4}- подряд 4 цифры[^\d]- любой символ кроме цифры$- конец строки|- оператор или.[^\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-х цифр - это просто либо не цифра либо же конец строки