Другое

Как проверить, является ли строка валидным числом для кода

Узнайте, как проверить, является ли строка числом в разных языках программирования. Практические примеры на Python, Java и JavaScript, функции и регулярные выражения.

Как определить, что строка представляет собой корректное число? Например:

  • "abc" должно вернуть false
  • "123" должно вернуть true
  • "ab2" должно вернуть false

Есть ли встроенная функция, как IsNumeric(), или другой способ проверить, содержит ли строка только числовые символы?

Чтобы определить, представляет ли строка действительное число, можно воспользоваться встроенными функциями, такими как isnumeric() в Python, StringUtils.isNumeric() в Java, Number.isFinite() в JavaScript или is_numeric() в PHP. Эти методы обеспечивают разный уровень проверки: от проверки, что все символы являются цифрами, до обработки полных форматов чисел, включая десятичные дроби, научную нотацию и отрицательные числа. Самый надёжный подход часто заключается в попытке преобразовать строку в число и отлавливании исключений, либо в использовании регулярных выражений для конкретных форматов чисел.

Содержание

Встроенные функции в различных языках программирования

Большинство современных языков программирования предоставляют встроенные функции для проверки, является ли строка допустимым числом. Эти функции различаются по степени специфичности и тому, что они считают «числовым».

Методы строк в Python

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 предоставляет надёжное решение:

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 предлагает современный подход:

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 обрабатывает различные форматы чисел:

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.

Подходы с регулярными выражениями

Регулярные выражения предоставляют гибкие способы сопоставления конкретных форматов чисел и могут быть настроены под разные требования.

Базовый шаблон числа

Для простых целых и десятичных чисел:

javascript
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 использует регулярные выражения для проверки:

java
public static boolean isNumericOne(String s) {
    return s.matches("-?\\d+(\\.\\d+)?"); // совпадение числа с опциональным '-' и десятичной точкой
}

Согласно обсуждению на Stack Overflow, это регулярное выражение обрабатывает базовые числовые шаблоны, но может не покрывать все крайние случаи.

Решение на Delphi/Free Pascal

Delphi предоставляет практический подход с использованием встроенных функций:

pascal
function IsNumericString(const inStr: string): Boolean;
var
  i: extended;
begin
  Result := TryStrToFloat(inStr, i);
end;

Из реализации на Rosetta Code эта функция использует TryStrToFloat для попытки преобразования и возвращает результат.

Методы проверки на основе исключений

Обработка исключений обеспечивает один из самых надёжных способов проверки числовых строк, пытаясь преобразовать строку и отлавливая возникающие исключения.

Подход с try‑except в Python

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()

java
public static boolean isNumeric(String str) {
    try {
        Double.parseDouble(str);
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}

Согласно уроку от Programiz, в блоке try используется Double.parseDouble() для преобразования строки в Double. Если исключения не возникает, строка считается числовой.

Подход с NumberFormat в Java

Для более сложной проверки:

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

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

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
// Множественные подходы к проверке чисел в 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)}`);
});

Источники

  1. Python String isnumeric() Method - W3Schools
  2. How can I check if a string is a valid number? - Stack Overflow
  3. Check If a String Is Numeric in Java - Baeldung
  4. How to check if a String is numeric in Java - Stack Overflow
  5. How to check if a String is a number in JavaScript - CoreUI
  6. Determine if a string is numeric - Rosetta Code
  7. Check if a given string is a valid number in Python - Tutorialspoint
  8. PHP: is_numeric - Manual
  9. Java Program to Check if a String is Numeric - Programiz
  10. How To Check If A String Is Numeric To Avoid NumberFormatException - Medium
  11. Java Numeric String Parsing - LabEx

Вывод

Определение того, является ли строка допустимым числом, требует понимания возможностей конкретного языка программирования и ваших требований к проверке. Ключевые выводы:

  • Встроенные функции (isnumeric(), isNumeric(), is_numeric()) дают быстрый контроль, но не всегда покрывают все форматы чисел.
  • Регулярные выражения обеспечивают гибкость для конкретных требований, но могут стать сложными.
  • Проверка на основе исключений с парсингом обычно является самым надёжным подходом.
  • Выбор метода зависит от конкретных нужд: простоты, производительности или полной поддержки форматов.

Для базовой проверки, когда нужно убедиться, что все символы являются цифрами, достаточно встроенных методов строк. Для надёжной проверки, включающей десятичные дроби, научную нотацию, отрицательные числа и различные форматы, рекомендуется использовать парсинг с обработкой исключений и, при необходимости, дополнительные проверки с помощью регулярных выражений. Всегда учитывайте конкретный случай использования и экосистему выбранного языка при выборе подходящего метода проверки.

Авторы
Проверено модерацией
Модерация