Python:时间输入验证

时间:2015-04-30 07:11:10

标签: python python-2.7 date

我有一个无法解决的问题, 我应该以{{1​​}}(hh:mm:ss)或10:10:10(mm:ss)或10:10(ss)的形式获得用户输入。现在我需要检查以下参数:

  • 如果我只获得了几秒钟,那就没有限制了。
  • 如果我获得10,则秒数限制为0..59,且分钟数不受限制。
  • 如果我获得mm:ss,那么秒和分钟都限制在0..59,而小时数则无限制。

然后返回一个TimeDelta对象。

天真的方法是编写乘法hh:mm:ss语句来检查所有这些。 但我正在寻找一种更顺畅的方式。

if

1 个答案:

答案 0 :(得分:7)

如何在这里使用正则表达式:

import re
import datetime
pattern = re.compile(r'^(\d+)(?::([0-5]?\d)(?::([0-5]?\d))?)?$')

def str2seconds(val):
    match = pattern.match(val)
    if not match:
        raise ValueError("Invalid input: %s" % val)
    else:
        result = 0
        for i in match.groups():
            if i is not None:
                result *= 60
                result += int(i)

    return datetime.timedelta(seconds=result)

示例:

>>> print(str2seconds('255'))
0:04:15
>>> print(str2seconds('255:25'))
4:15:25
>>> print(str2seconds('255:25:25'))
10 days, 15:25:25
>>> print(str2seconds('255:25:25:255'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "y.py", line 8, in str2seconds
    raise ValueError("Invalid input: %s" % val)
ValueError: Invalid input: 255:25:25:255
>>> print(str2seconds('255:25:60'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "y.py", line 8, in str2seconds
    raise ValueError("Invalid input: %s" % val)
ValueError: Invalid input: 255:25:60

正则表达式逐个部分:

  • ^:字符串的开头
  • (\d+):1-n位数,被捕获为第1组
  • (?::([0-5]?\d)(?::([0-5]?\d))?)?可选部分:
    • (?:...)是一个非捕获组
    • :与文字:
    • 相匹配
    • ([0-5]?\d)一个可选的数字0-5,后跟一个数字,被捕获为第2组
    • 第一个中有第二个非捕获组: (?::([0-5]?\d))?可选地匹配第二个:后跟 一个可选的数字0-5后跟一个数字;并将数字捕获到第3组
    • 最后$匹配字符串的结尾。严格地说,开头的^不是必需的,因为match在开始时锚定了匹配;但是$是必要的,否则匹配不会锚定在字符串的末尾! (Python 3.4添加the re.fullmatch来修复此问题。)

match.groups()将是3个项目的元组;不匹配的组将以None返回。