Регулярное выражение для чисел с разделителем (к примеру 1_000)
Возникла задача проверять, имеет ли число разделитель, если имеет, возвращать true, соответственно сам литерал тоже должен быть валидным. Попытался сделать вот так:
const reSeparatedLiteral = /^\d(_{1,1}|\d)+\d$/
const data = [{
str: '1_000',
expected: true,
},{
str: '10_00',
expected: true,
},{
str: '1_0_0_0',
expected: true,
},{
str: '_1_000',
expected: false,
},{
str: '1_000_',
expected: false,
},{
str: '1__000',
expected: false,
},{
str: '1000',
expected: false,
}]
test(reSeparatedLiteral)
function test(re) {
for (let i = 0; i < data.length; i++) {
let currentData = data[i]
let { str, expected } = currentData
if(re.test(str) === expected) {
console.log('✅ Test is passed!', str)
} else {
console.log('❌ Test is not passed!', str)
}
}
}
В данном случае у меня возникло две проблемы:
- Как проверять, что число точно имеет разделитель? (Несовсем уверен как работать с аналогом оператор AND в регулярных варжения (я про это:
(?=...)(?=...)), но уверен, что эту проблему можно решить используя подобную запись) - Как проверять, что разделитель это только один символ, а не два?
Про первую проблему. Я попытался делать что-то типа такого: /(?=^\d(_{1,1}|\d)+\d$)(?=^[\D]+$)/, но из-за этого, ни первая, ни вторая строка не проходят проверку.
Важное уточнение: нужно использовать исключительно регулярное выражение, то есть использование строковых методов, не вариант.
P.S. такие числа (литералы) по настоящему поддерживаются в JavaScript, то есть вы можете записать миллион в таком виде: 1_000_000, чтобы сделать его (число) более читаемым.
Ответы (1 шт):
Что не так с ^\d(_{1,1}|\d)+\d$? Строка, соответствующая выражения, должна начинаться с цифры, за которой должен следовать один или более повторов цифры или знака подчёркивания, а потом цифра в конце строки. Обратите внимание, что {1,1} можно всегда удалять, ^\d(_{1,1}|\d)+\d$ = ^\d(_|\d)+\d$ = ^\d[_\d]+\d$.
Решение
^\d+(?:_\d+)+$
См. пример регулярного выражения.
Подробности
^- начало строки\d+- одна или более цифр(?:_\d+)+- один и более повторов последовательности из_и одной и более цифр (из-за того, что требуется одна и более цифр после_, двойной символ подчёркивания в строке невозможен)$- конец строки.
Пример:
const reSeparatedLiteral = /^\d+(?:_\d+)+$/
const data = [{
str: '1_000',
expected: true,
},{
str: '10_00',
expected: true,
},{
str: '1_0_0_0',
expected: true,
},{
str: '_1_000',
expected: false,
},{
str: '1_000_',
expected: false,
},{
str: '1__000',
expected: false,
},{
str: '1000',
expected: false,
}]
test(reSeparatedLiteral)
function test(re) {
for (let i = 0; i < data.length; i++) {
let currentData = data[i]
let { str, expected } = currentData
if(re.test(str) === expected) {
console.log('✅ Test is passed!', str)
} else {
console.log('❌ Test is not passed!', str)
}
}
}