Шаг 81.
Однострочники Python. Регулярные выражения. Проверка формата времени во вводимых пользователем данных, часть 1

    На этом шаге мы рассмотрим алгоритм решения этой задачи.

    Научимся проверять правильность формата вводимых пользователем данных. Пусть вы пишете веб-приложение, вычисляющее медицинские показатели на основе длительности сна пользователей. Они вводят время отхода ко сну и время пробуждения. Пример времени в правильном формате - 12:45, но из-за спама от веб-ботов большое количество испорченных данных приводит к излишней вычислительной нагрузке на сервер. Для решения этой проблемы вы хотите написать средство проверки формата времени, которое бы определяло, имеет ли смысл дальнейшая обработка ваших входных данных приложением, расположенным в прикладной части. Написание такого кода с помощью регулярных выражений занимает всего несколько минут.

Общее описание

    В предыдущих нескольких шагах вы узнали про функции re.match(), re.search() и re.findall(). Они не единственные функции для работы с регулярными выражениями. На этом шаге мы воспользуемся функцией re.fullmatch(регулярное_выраженuе, строковое_значение), проверяющей, соответствует ли регулярному выражению полное строковое_значение, как можно предположить из ее названия.

    Кроме того, мы воспользуемся синтаксисом <шаблон>{m,n} регулярных выражений, применяемым для поиска строки символов, включающей от m до n копий шаблон, но не более и не менее данного количества. Обратите внимание, что при этом производится попытка найти строку символов с максимальным количеством вхождений <шаблон>. Ниже представлен пример:

import re

print(re.findall('x{3,5}y', 'xy'))
# []

print(re.findall('x{3,5}y', 'xxxy'))
# ['xxxy']

print(re.findall('x{3,5}y', 'xxxxxy'))
# ['xxxxxy']

print(re.findall('x{3,5}y', 'xxxxxxy'))
# ['xxxxxy']

    При использовании нотации с фигурными скобками код не ищет соответствий подстрок, включающих менее трех и более пяти символов 'x'.

Код

    Наша задача - написать функцию input_ok, принимающую строковый аргумент и проверяющий его на соответствие формату (времени) XX:XX, где X - число от 0 до 9 (пример 5.6). Учтите, что пока мы не отбрасываем семантически неправильные форматы времени наподобие 12:86. Этой более сложной задачей мы займемся на следующем шаге.


Пример 5.6. Однострочное решение для проверки соответствия введенных пользователем данных общему формату времени XX:XX
## Зависимости
import re

## Данные
inputs = ['18:29', '23:55', '123', 'ab:de', '18:299', '99:99']

## Однострочник
input_ok = lambda x: re.fullmatch('[0-9]{2}:[0-9]{2}', x) != None

## Результат
for x in inputs:
    print(input_ok(x))
Архив с файлом можно взять здесь.

    Прежде чем продолжить чтение, попробуйте определить результаты шести вызовов функций в этом коде.

Принцип работы

    Наши данные состоят из шести входных строковых значений, получаемых клиентской частью веб-приложения. Правильного ли они формата? Чтобы проверить, мы создаем функцию input_ok с помощью лямбда-выражения с одним входным аргументом x и булевым выходным значением. Далее с помощью функции fullmatch(регулярное_выраженuе, x) мы пытаемся установить соответствие входному аргументу x нашему регулярному выражению для формата времени. Если это не удается, то результат принимает значение None, а булев выходной результат функции - False. В противном случае булев результат функции будет True.

    Само регулярное выражение очень простое: [0-9]{2}: [0-9]{2}. Ему соответствуют два числа от 0 до 9, за которыми следует двоеточие :, за которым следуют еще два числа от 0 до 9. Таким образом, результат примера 5.6 выглядит следующим образом:

## Результат
for x in inputs:
    print(input_ok(x))

# True
# True
# False
# False
# False
# True

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

    На следующем шаге мы закончим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг