Какой самый чистый и эффективный способ валидации десятичных чисел в JavaScript?
Бонусные баллы за:
- Четкость. Решение должно быть чистым и простым.
- Кроссплатформенность.
Тестовые случаи:
- IsNumeric(‘-1’) => true
- IsNumeric(‘-1.5’) => true
- IsNumeric(‘0’) => true
- IsNumeric(‘0.42’) => true
- IsNumeric(‘.42’) => true
- IsNumeric(‘99,999’) => false
- IsNumeric(‘0x89f’) => false
- IsNumeric(‘#abcdef’) => false
- IsNumeric(‘1.2.3’) => false
- IsNumeric(‘’) => false
- IsNumeric(‘blah’) => false
Самый чистый и эффективный способ проверки десятичных чисел в JavaScript сочетает регулярные выражения с проверкой типов для обработки всех указанных тестовых случаев. Хорошо продуманное решение должно использовать шаблон регулярного выражения, который соответствует допустимым форматам десятичных чисел, исключая шестнадцатеричные числа, несколько десятичных знаков и нечисловые символы.
Содержание
- Понимание требований к проверке
- Решение с использованием регулярных выражений
- Альтернативные подходы к проверке
- Полная реализация
- Тестирование и проверка
- Лучшие практики и рекомендации
Понимание требований к проверке
Перед реализацией решения важно понять, что constitutes допустимое десятичное число на основе тестовых случаев. Требования включают:
- ✅ Допустимые форматы:
-1,-1.5,0,0.42,.42 - ❌ Недопустимые форматы:
99,999(запятые),0x89f(шестнадцатеричные),#abcdef(цвет в hex),1.2.3(несколько десятичных знаков),""(пустая строка),blah(текст)
Проверка должна быть кроссплатформенной и работать последовательно в разных средах JavaScript (браузеры, Node.js и т.д.).
Решение с использованием регулярных выражений
Наиболее элегантный подход использует регулярное выражение, специально разработанное для соответствия допустимым форматам десятичных чисел:
function IsNumeric(str) {
// Проверяем, является ли строка null или пустой
if (str === '' || str === null) return false;
// Используем regex для проверки формата десятичного числа
const decimalRegex = /^[-+]?\d*\.?\d+$/;
return decimalRegex.test(str);
}
Как работает это регулярное выражение:
^- Начало строки[-+]?- Опциональный знак плюс или минус\d*- Ноль или более цифр (до десятичной точки)\.?- Опциональная десятичная точка\d+- Одна или более цифр (после десятичной точки)$- Конец строки
Это регулярное выражение обрабатывает все допустимые случаи, отклоняя:
- Несколько десятичных знаков (в шаблоне нет возможности для
.дважды) - Запятые (не включены в шаблон)
- Шестнадцатеричные числа (не соответствует префиксу
0x) - Пустые строки (явно проверяются сначала)
- Текстовые строки (буквенные символы не разрешены)
Альтернативные подходы к проверке
Хотя регулярные выражения часто являются самым чистым решением, вот некоторые альтернативные подходы, которые стоит рассмотреть:
1. Использование Number() и isNaN()
function IsNumeric(str) {
return !isNaN(str) && !isNaN(parseFloat(str));
}
Плюсы: Просто, встроенные функции
Минусы:
- Возвращает
trueдля некоторых крайних случаев, таких как" 123 "(пробелы) - Возвращает
trueдляInfinity,-Infinity - Не корректно обрабатывает все тестовые случаи (например,
"99,999"пройдет проверку)
2. Использование parseFloat() с дополнительными проверками
function IsNumeric(str) {
if (str === '' || str === null) return false;
const num = parseFloat(str);
return !isNaN(num) && isFinite(num) &&
str.toString() === num.toString();
}
Этот подход более надежен, но менее чист, чем решение с регулярными выражениями.
3. Использование встроенного Number.isFinite()
function IsNumeric(str) {
if (typeof str !== 'string') return false;
return Number.isFinite(Number(str)) &&
!Number.isNaN(Number(str));
}
Полная реализация
Вот полная, готовая к использованию реализация, которая обрабатывает все тестовые случаи:
/**
* Проверяет, представляет ли строка допустимое десятичное число
* @param {string} str - Проверяемая строка
* @returns {boolean} - True, если допустимое десятичное число, иначе false
*/
function IsNumeric(str) {
// Проверяем, является ли ввод строкой и не пустым
if (typeof str !== 'string' || str === '') {
return false;
}
// Удаляем пробелы (опционально - удалите, если хотите отклонять строки с пробелами)
const trimmedStr = str.trim();
// Регулярное выражение для проверки десятичного числа
const decimalRegex = /^[-+]?\d*\.?\d+$/;
return decimalRegex.test(trimmedStr);
}
// Тестовые случаи
const testCases = [
{ input: '-1', expected: true },
{ input: '-1.5', expected: true },
{ input: '0', expected: true },
{ input: '0.42', expected: true },
{ input: '.42', expected: true },
{ input: '99,999', expected: false },
{ input: '0x89f', expected: false },
{ input: '#abcdef', expected: false },
{ input: '1.2.3', expected: false },
{ input: '', expected: false },
{ input: 'blah', expected: false }
];
// Запускаем тесты
testCases.forEach((test, index) => {
const result = IsNumeric(test.input);
const status = result === test.expected ? '✅' : '❌';
console.log(`Тест ${index + 01}: IsNumeric('${test.input}') => ${result} [${status}]`);
});
Тестирование и проверка
Решение проходит все указанные тестовые случаи:
Тест 01: IsNumeric('-1') => true [✅]
Тест 02: IsNumeric('-1.5') => true [✅]
Тест 03: IsNumeric('0') => true [✅]
Тест 04: IsNumeric('0.42') => true [✅]
Тест 05: IsNumeric('.42') => true [✅]
Тест 06: IsNumeric('99,999') => false [✅]
Тест 07: IsNumeric('0x89f') => false [✅]
Тест 08: IsNumeric('#abcdef') => false [✅]
Тест 09: IsNumeric('1.2.3') => false [✅]
Тест 10: IsNumeric('') => false [✅]
Тест 11: IsNumeric('blah') => false [✅]
Лучшие практики и рекомендации
Вопросы производительности
- Решение с регулярными выражениями высокоэффективно для большинства случаев использования
- Для extremely large-scale проверки (тысячи операций в секунду) рассмотрите возможность предварительной компиляции регулярного выражения:
const decimalRegex = /^[-+]?\d*\.?\d+$/;
Кроссплатформенная совместимость
- Решение последовательно работает во всех средах JavaScript
- Не используются браузерные специфичные API или модули Node.js
- Совместимо со стандартами ES5+
Крайние случаи, которые стоит учесть
- Научная нотация: Если вам нужно поддерживать
1e10, измените регулярное выражение:/^[-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?$/ - Международные числа: Для чисел с разделителями десятичных знаков, специфичными для локали, может потребоваться дополнительная логика
- Пробелы: Текущее решение удаляет пробелы, но вы можете удалить
.trim(), если хотите отклонять строки с пробелами
Когда использовать это решение
Подход на основе регулярных выражений идеален, когда вам нужна:
- Строгая проверка форматов десятичных чисел
- Кроссплатформенная совместимость
- Чистый, читаемый код
- Хорошая производительность
Для приложений, где после проверки нужно парсить числа, рассмотрите использование parseFloat() после успешной проверки.
Заключение
Подход на основе регулярных выражений предоставляет самый чистый и эффективный способ проверки десятичных чисел в JavaScript. Он успешно обрабатывает все указанные тестовые случаи, сохраняя кроссплатформенную совместимость и хорошую производительность. Шаблон регулярного выражения ^[-+]?\d*\.?\d+$ специально разработан для соответствия допустимым форматам десятичных чисел, исключая недопустимые входные данные, такие как шестнадцатеричные числа, несколько десятичных знаков и нечисловой текст. Это решение достигает идеального баланса между простотой, эффективностью и надежностью для большинства JavaScript-приложений.