Как проверить, является ли строка валидным числом для кода
Узнайте, как проверить, является ли строка числом в разных языках программирования. Практические примеры на Python, Java и JavaScript, функции и регулярные выражения.
Как определить, что строка представляет собой корректное число? Например:
"abc"должно вернутьfalse"123"должно вернутьtrue"ab2"должно вернутьfalse
Есть ли встроенная функция, как IsNumeric(), или другой способ проверить, содержит ли строка только числовые символы?
Чтобы определить, представляет ли строка действительное число, можно воспользоваться встроенными функциями, такими как isnumeric() в Python, StringUtils.isNumeric() в Java, Number.isFinite() в JavaScript или is_numeric() в PHP. Эти методы обеспечивают разный уровень проверки: от проверки, что все символы являются цифрами, до обработки полных форматов чисел, включая десятичные дроби, научную нотацию и отрицательные числа. Самый надёжный подход часто заключается в попытке преобразовать строку в число и отлавливании исключений, либо в использовании регулярных выражений для конкретных форматов чисел.
Содержание
- Встроенные функции в различных языках программирования
- Подходы с регулярными выражениями
- Методы проверки на основе исключений
- Сравнение различных техник проверки
- Практические примеры реализации
Встроенные функции в различных языках программирования
Большинство современных языков программирования предоставляют встроенные функции для проверки, является ли строка допустимым числом. Эти функции различаются по степени специфичности и тому, что они считают «числовым».
Методы строк в Python
Python предлагает несколько методов строк для проверки числовости:
# Базовая проверка
"123".isnumeric() # True
"abc".isnumeric() # False
"ab2".isnumeric() # False
# Для десятичных точек и отрицательных чисел
"123".isdigit() # True
"123.45".isdigit() # False
Согласно документации W3Schools по Python, метод isnumeric() возвращает True, если все символы в строке являются цифрами (0‑9), иначе False. Однако этот метод не обрабатывает десятичные точки, отрицательные знаки или научную нотацию.
StringUtils.isNumeric() в Java
Apache Commons Lang в Java предоставляет надёжное решение:
// Из класса StringUtils
StringUtils.isNumeric("123"); // true
StringUtils.isNumeric("123.45"); // false
StringUtils.isNumeric("-123"); // false
Как объясняет Baeldung, метод StringUtils.isNumeric(CharSequence) проверяет строго наличие Unicode‑цифр, то есть любые цифры из любого языка, которые являются Unicode‑цифрами, считаются допустимыми. Поскольку десятичная точка не считается Unicode‑цифрой, она не проходит проверку.
Number.isFinite() в JavaScript
JavaScript предлагает современный подход:
const isNumeric = (string) => Number.isFinite(+string)
console.log(isNumeric('12345')) // true
console.log(isNumeric('123.45')) // true
console.log(isNumeric('-123')) // true
console.log(isNumeric('abc')) // false
console.log(isNumeric('ab2')) // false
Согласно руководству CoreUI по JavaScript, функция Number.isFinite() обеспечивает элегантное решение для идентификации числовых значений при совместном использовании с преобразованием типов.
is_numeric() в PHP
Встроенная функция PHP обрабатывает различные форматы чисел:
is_numeric('123'); // true
is_numeric('123.45'); // true
is_numeric('-123'); // true
is_numeric('abc'); // false
is_numeric('ab2'); // false
is_numeric('42,1'); // false (запятая вместо точки)
Согласно документации PHP, для строк is_numeric() возвращает true только если число с плавающей точкой содержит точку, поэтому is_numeric('42.1') возвращает true, а is_numeric('42,1') — false.
Подходы с регулярными выражениями
Регулярные выражения предоставляют гибкие способы сопоставления конкретных форматов чисел и могут быть настроены под разные требования.
Базовый шаблон числа
Для простых целых и десятичных чисел:
const NUMBER_REG_EXP = /^-?\d+(\.\d+)?$/;
const SCIENTIFIC_NOTATION_REG_EXP = /^-?\d+(\.\d+)?(?:[eE]\d+)?$/;
const isNumeric = (n, allowScientificNotation = false) => {
return (
(typeof n === 'number' && !Number.isNaN(n)) ||
(typeof n === 'string' && (allowScientificNotation ?
SCIENTIFIC_NOTATION_REG_EXP.test(n) :
NUMBER_REG_EXP.test(n)))
);
};
Как показано в ответе на Stack Overflow, этот подход покрывает базовые случаи и при необходимости обрабатывает научную нотацию.
Реализация на Java
Java использует регулярные выражения для проверки:
public static boolean isNumericOne(String s) {
return s.matches("-?\\d+(\\.\\d+)?"); // совпадение числа с опциональным '-' и десятичной точкой
}
Согласно обсуждению на Stack Overflow, это регулярное выражение обрабатывает базовые числовые шаблоны, но может не покрывать все крайние случаи.
Решение на Delphi/Free Pascal
Delphi предоставляет практический подход с использованием встроенных функций:
function IsNumericString(const inStr: string): Boolean;
var
i: extended;
begin
Result := TryStrToFloat(inStr, i);
end;
Из реализации на Rosetta Code эта функция использует TryStrToFloat для попытки преобразования и возвращает результат.
Методы проверки на основе исключений
Обработка исключений обеспечивает один из самых надёжных способов проверки числовых строк, пытаясь преобразовать строку и отлавливая возникающие исключения.
Подход с try‑except в Python
def is_numeric(s):
try:
float(s)
return True
except ValueError:
return False
# Тестовые случаи
print(is_numeric("123")) # True
print(is_numeric("123.45")) # True
print(is_numeric("-123")) # True
print(is_numeric("abc")) # False
print(is_numeric("ab2")) # False
Как отмечает Tutorialspoint, этот метод пытается преобразовать строку в число и возвращает, возникло ли исключение.
Try‑Catch в Java с Double.parseDouble()
public static boolean isNumeric(String str) {
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
Согласно уроку от Programiz, в блоке try используется Double.parseDouble() для преобразования строки в Double. Если исключения не возникает, строка считается числовой.
Подход с NumberFormat в Java
Для более сложной проверки:
import java.text.NumberFormat;
import java.text.ParsePosition;
public static boolean isNumeric(String s) {
ParsePosition pos = new ParsePosition(0);
NumberFormat.getInstance().parse(s, pos);
return s.length() == pos.getIndex();
}
Как описано в руководстве Medium, этот подход использует метод parse NumberFormat и проверяет, была ли вся строка полностью обработана.
Сравнение различных техник проверки
| Метод | Плюсы | Минусы | Лучшее применение |
|---|---|---|---|
| Встроенные функции | Простые, быстрые, нативные | Ограниченная функциональность, не покрывают все случаи | Быстрая проверка базовых числовых строк |
| Регулярные выражения | Гибкие, настраиваемые под конкретные форматы | Сложные шаблоны могут быть трудны для чтения, производительность варьируется | Требования к конкретному формату числа |
| Обработка исключений | Самый надёжный, обрабатывает сложные форматы | Перегрузка производительности в некоторых языках | Надёжная проверка, когда точность критична |
| Библиотеки StringUtils | Полноценные, обрабатывают крайние случаи | Требуется внешняя зависимость | Производственные приложения, требующие надёжности |
Согласно уроку от LabEx, парсинг является самым простым и надёжным способом определить, является ли строка числом в Java, и Java предоставляет различные встроенные методы парсинга для этой цели.
Практические примеры реализации
Полное решение на Python
def is_valid_number(s):
"""Проверить, представляет ли строка допустимое число."""
try:
float(s)
return True
except ValueError:
return False
# Расширенная версия с указанием формата
def is_valid_number_format(s, allow_scientific=True, allow_hex=False):
"""Проверить, соответствует ли строка конкретным форматам чисел."""
if allow_hex and s.startswith(('0x', '0X', '#')):
try:
int(s, 16)
return True
except ValueError:
pass
try:
float(s)
return True
except ValueError:
if allow_scientific and 'e' in s.lower():
# Обработка научной нотации отдельно
try:
float(s)
return True
except ValueError:
pass
return False
# Тестовые случаи
test_cases = ["123", "123.45", "-123", "abc", "ab2", "1e10", "0xFF"]
for case in test_cases:
print(f"'{case}': {is_valid_number(case)}")
Полное решение на Java
import java.text.NumberFormat;
import java.text.ParsePosition;
public class NumericValidator {
// Простая проверка на основе исключений
public static boolean isNumeric(String str) {
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
// Полная проверка с NumberFormat
public static boolean isNumericComprehensive(String s) {
ParsePosition pos = new ParsePosition(0);
NumberFormat.getInstance().parse(s, pos);
return s.length() == pos.getIndex();
}
// Проверка с помощью регулярного выражения
public static boolean isNumericRegex(String str) {
return str.matches("-?\\d+(\\.\\d+)?([eE][-+]?\\d+)?");
}
// Тестовая функция
public static void main(String[] args) {
String[] testCases = {"123", "123.45", "-123", "abc", "ab2", "1e10", "0xFF"};
for (String testCase : testCases) {
System.out.printf("'%s': Exception=%b, NumberFormat=%b, Regex=%b%n",
testCase, isNumeric(testCase), isNumericComprehensive(testCase),
isNumericRegex(testCase));
}
}
}
Полное решение на JavaScript
// Множественные подходы к проверке чисел в JavaScript
// 1. С использованием Number.isFinite
function isNumericModern(str) {
return Number.isFinite(+str);
}
// 2. Подход с регулярным выражением
function isNumericRegex(str) {
return /^-?\d+(\.\d+)?([eE][-+]?\d+)?$/.test(str);
}
// 3. Полная проверка
function isNumericComprehensive(str) {
if (typeof str !== 'string') return false;
// Удаляем пробелы
str = str.trim();
// Пустая строка
if (str === '') return false;
// Проверка на шестнадцатеричное число
if (str.startsWith('0x') || str.startsWith('0X')) {
return /^[0-9A-Fa-f]+$/.test(str.substring(2));
}
// Проверка научной нотации
if (str.includes('e') || str.includes('E')) {
const [base, exponent] = str.split(/[eE]/);
return isNumericRegex(base) && /^[-+]?\d+$/.test(exponent);
}
// Обычная проверка числа
return isNumericRegex(str);
}
// Тестовые случаи
const testCases = ["123", "123.45", "-123", "abc", "ab2", "1e10", "0xFF"];
testCases.forEach(testCase => {
console.log(`'${testCase}': Modern=${isNumericModern(testCase)}, ` +
`Regex=${isNumericRegex(testCase)}, ` +
`Comprehensive=${isNumericComprehensive(testCase)}`);
});
Источники
- Python String isnumeric() Method - W3Schools
- How can I check if a string is a valid number? - Stack Overflow
- Check If a String Is Numeric in Java - Baeldung
- How to check if a String is numeric in Java - Stack Overflow
- How to check if a String is a number in JavaScript - CoreUI
- Determine if a string is numeric - Rosetta Code
- Check if a given string is a valid number in Python - Tutorialspoint
- PHP: is_numeric - Manual
- Java Program to Check if a String is Numeric - Programiz
- How To Check If A String Is Numeric To Avoid NumberFormatException - Medium
- Java Numeric String Parsing - LabEx
Вывод
Определение того, является ли строка допустимым числом, требует понимания возможностей конкретного языка программирования и ваших требований к проверке. Ключевые выводы:
- Встроенные функции (
isnumeric(),isNumeric(),is_numeric()) дают быстрый контроль, но не всегда покрывают все форматы чисел. - Регулярные выражения обеспечивают гибкость для конкретных требований, но могут стать сложными.
- Проверка на основе исключений с парсингом обычно является самым надёжным подходом.
- Выбор метода зависит от конкретных нужд: простоты, производительности или полной поддержки форматов.
Для базовой проверки, когда нужно убедиться, что все символы являются цифрами, достаточно встроенных методов строк. Для надёжной проверки, включающей десятичные дроби, научную нотацию, отрицательные числа и различные форматы, рекомендуется использовать парсинг с обработкой исключений и, при необходимости, дополнительные проверки с помощью регулярных выражений. Всегда учитывайте конкретный случай использования и экосистему выбранного языка при выборе подходящего метода проверки.