Python: методы валидации строк как числовых значений

Раздел: Основы Python -> Проверки чисел

Основные подходы к проверке строки на число

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

Основной эффективный способ: try/except с преобразованием в float

Наиболее универсальный метод - попытаться преобразовать строку в число с плавающей точкой (float) и перехватить исключение ValueError. Он корректно обрабатывает целые и дробные числа, отрицательные значения, научную нотацию (например, '1e5').

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

print(is_number('123'))      # True
print(is_number('3.14'))     # True
print(is_number('-7'))       # True
print(is_number('1.2e3'))    # True
print(is_number('abc'))      # False
print(is_number(''))         # False

строка является числом python (проверка, является ли строка числом (isdigit, try/except) в python)

Объяснение: функция float(s) пытается преобразовать строку. Если это невозможно, вызывается ValueError, и функция возвращает False. Метод не требует дополнительных проверок на знак или десятичную точку.

Возможные проблемы:

  • Функция float принимает строки 'inf', '-inf', 'nan', что может быть нежелательно. В таких случаях нужно дополнительно проверять результат:
def is_number_strict(s):
    try:
        val = float(s)
        return not (val != val or val == float('inf') or val == float('-inf'))
    except ValueError:
        return False

print(is_number_strict('nan'))  # False
print(is_number_strict('inf'))  # False

является ли число целым python (проверка, является ли число целым (int) в python)

  • Пустая строка всегда вызывает исключение, поэтому дополнительная обработка не требуется.

Как проверить строку на целое положительное число с помощью isdigit?

Метод str.isdigit() возвращает True, если все символы строки являются десятичными цифрами (0-9) и строка не пуста. Он подходит только для целых неотрицательных чисел без знака и десятичных разделителей.

s = '12345'
print(s.isdigit())  # True

s = '12a34'
print(s.isdigit())  # False

s = '-123'
print(s.isdigit())  # False

s = ''
print(s.isdigit())  # False

Когда использовать: если гарантировано, что число целое и неотрицательное, например, при проверке ввода количества товаров, года рождения и т.п.

Типичная ошибка: новички используют isdigit для проверки любых чисел, забывая о знаке минус, десятичной точке или отрицательных значениях. Это приводит к ложным отрицательным результатам.

Чем отличается isnumeric от isdecimal?

Методы str.isnumeric() и str.isdecimal() похожи на isdigit, но работают с более широким набором символов. isnumeric возвращает True для цифр, дробных символов (например, ½), римских чисел и других числовых обозначений. isdecimal допускает только десятичные цифры (0-9, а также арабско-индийские и т.п.).

s = '123'
print(s.isdecimal())  # True
print(s.isnumeric())  # True

s = '½'
print(s.isdecimal())  # False
print(s.isnumeric())  # True

s = '①②③'
print(s.isdecimal())  # False
print(s.isnumeric())  # True
print(s.isdigit())    # True (окружные цифры считаются цифрами)

Когда использовать: для локализованного ввода, где возможны цифры из других письменностей или дроби.

Как проверить целое число со знаком с помощью int и try/except?

Если требуется только целое число (включая отрицательное), удобно использовать преобразование в int:

def is_integer(s):
    try:
        int(s)
        return True
    except ValueError:
        return False

print(is_integer('42'))    # True
print(is_integer('-5'))    # True
print(is_integer('3.14'))  # False
print(is_integer(''))      # False

Ограничение: не принимает дробные числа, числа в научной нотации (1e5), но допускает ведущие и хвостовые пробелы (int(' 123 ') вернет 123).

Проблема: int('+7') также работает, что может быть удобно, но требуется внимательность при строгой проверке.

Как использовать регулярные выражения для проверки строки на число?

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

import re

def is_number_regex(s):
    pattern = r'^[+-]?\d+(\.\d+)?$'
    return bool(re.match(pattern, s))

print(is_number_regex('3.14'))   # True
print(is_number_regex('1e5'))    # False
print(is_number_regex('-7'))     # True
print(is_number_regex('+0.5'))   # True
print(is_number_regex('.'))      # False
print(is_number_regex('12.'))    # False

Когда использовать: когда необходим жёсткий контроль формата числа, например, при парсинге файлов с известной структурой.

Общие проблемы и их решение:

  • Пробел в строке: методы isdigit/isnumeric не допускают пробелов, try/except с int/float игнорируют ведущие/хвостовые пробелы. Для строгой проверки используйте s.strip() или регулярные выражения.
  • Научная нотация: только try/except с float обрабатывает '1e3', isdigit и int - нет.
  • Пустая строка: все методы кроме try/except могут дать неверный результат; isdigit для пустой строки возвращает False, что корректно.

Цели и случаи использования:

  • isdigit/isnumeric/isdecimal - быстрые проверки без исключений, когда известен тип числа (целое неотрицательное, числовой символ).
  • try/except с float - универсальный способ для любых числовых строк, включая отрицательные, дробные, научную нотацию. Рекомендуется как базовый.
  • try/except с int - если нужно только целое (со знаком).
  • Регулярные выражения - когда формат числа строго определён и требуется отсечь нестандартные записи.

Расширенные примеры проверки строки на число

Ниже приведены более сложные сценарии, которые помогут глубже понять нюансы каждого подхода.

Пример 1: Проверка списка строк и преобразование в числа

Пример
def try_parse_list(strings):
    numbers = []
    invalid = []
    for s in strings:
        try:
            numbers.append(float(s))
        except ValueError:
            invalid.append(s)
    return numbers, invalid

data = ['10', '3.14', '-2.5', 'abc', '1e2', 'inf', '']
nums, errs = try_parse_list(data)
print('Числа:', nums)        # [10.0, 3.14, -2.5, 100.0, inf]
print('Ошибки:', errs)       # ['abc', '']
Числа: [10.0, 3.14, -2.5, 100.0, inf]

Пример 2: Строгая проверка целых чисел без знака плюс

Пример
def is_strict_positive_int(s):
    return s.isdigit() and s[0] != '0' if len(s) > 1 else s.isdigit()

print(is_strict_positive_int('0'))     # True
print(is_strict_positive_int('0123'))  # False
print(is_strict_positive_int('123'))   # True
print(is_strict_positive_int('+5'))    # False

Пример 3: Использование isnumeric для извлечения числовых символов из строки

Пример
mixed = 'Комната №123, цена 99.50$'
numeric_chars = [c for c in mixed if c.isnumeric()]
print('Цифры и числовые символы:', ''.join(numeric_chars))
Цифры и числовые символы: 1239950

Пример 4: Проверка с учётом тысяч разделителей (точка или запятая)

Пример
import re

def is_number_with_sep(s):
    # допускается: 1,234.56 или 1.234,56 (европейский формат)
    pattern = r'^[+-]?\d{1,3}([.,]?\d{3})*([.,]\d+)?$'
    return bool(re.match(pattern, s))

print(is_number_with_sep('1,234.56'))   # True
print(is_number_with_sep('1.234,56'))   # True
print(is_number_with_sep('1234567'))    # True
print(is_number_with_sep('12,34'))      # False

Пример 5: Фабричная функция для выбора стратегии проверки

Пример
def make_number_checker(mode='float'):
    if mode == 'int':
        return lambda s: s.lstrip('-+').isdigit()
    elif mode == 'digit':
        return lambda s: s.isdigit()
    elif mode == 'regex':
        p = re.compile(r'^[+-]?\d+(\.\d+)?$')
        return lambda s: bool(p.match(s))
    else:
        def float_check(s):
            try:
                float(s)
                return True
            except ValueError:
                return False
        return float_check

checker = make_number_checker('int')
print(checker('42'))    # True
print(checker('3.14'))  # False

Пример 6: Проверка на число с игнорированием ведущих и хвостовых пробелов

Пример
def is_number_strip(s):
    return s.strip().isdigit()  # для целых неотрицательных

print(is_number_strip('  123  '))  # True
print(is_number_strip('  -7  '))   # False

Пример 7: Обработка специфического требования - только положительные целые без лишних символов

Пример
def is_unsigned_int(s):
    if not s:
        return False
    for ch in s:
        if ch not in '0123456789':
            return False
    return True

print(is_unsigned_int('007'))   # True
print(is_unsigned_int(''))      # False
print(is_unsigned_int('12a'))   # False

Проверка, является ли строка числом (isdigit, try/except) в Python - comments

En
строка является числом python (python)