我有一个无法解决的问题,
我应该以{{1}}(hh:mm:ss)或10:10:10
(mm:ss)或10:10
(ss)的形式获得用户输入。现在我需要检查以下参数:
10
,则秒数限制为0..59,且分钟数不受限制。mm:ss
,那么秒和分钟都限制在0..59,而小时数则无限制。然后返回一个TimeDelta对象。
天真的方法是编写乘法hh:mm:ss
语句来检查所有这些。
但我正在寻找一种更顺畅的方式。
if
答案 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
返回。