Python:时间输入验证

Mic*_*elR 7 python date python-2.7

我有一个问题,我应该以10:10:10(hh:mm:ss)或10:10(mm:ss)或10(ss)的形式获得用户输入.现在我需要检查以下参数:

  • 如果我只有几秒钟,那么没有限制.
  • 如果我得到mm:ss那么秒被限制为0..59并且分钟是无限的.
  • 如果我得到了,hh:mm:ss那么秒和分钟都限制在0..59,而小时是无限的.

然后返回一个TimeDelta对象.

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

val = "11:66:11"
try:
    val = map(int, val.split(':'))
except ValueError:
    return False
if len(val) == 1:
    return val
if len(val) == 2:
    if val[1] > 59:
        print  "Bad seconds"
        return False
if len(val) == 3:
    if val[2] > 59 or val[1] >59:
        print  "Bad seconds / minutes"
        return False
while len(val) < 3:
        split.insert(0,0)
return = timedelta(hours=split[0],minutes=split[1],seconds=split[2])
Run Code Online (Sandbox Code Playgroud)

Ant*_*ala 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)
Run Code Online (Sandbox Code Playgroud)

例:

>>> 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
Run Code Online (Sandbox Code Playgroud)

正则表达式部分:

  • ^:字符串的开头
  • (\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添加re.fullmatch修复它.)

match.groups()将是3项的元组; 不匹配的组将作为返回None.