我正在尝试创建一个预订系统,其中来自用户的必填字段是#h#m#s
中的“预订时间”(小时-分钟)。需要一个或多个选项的地方。有没有一种方法可以很好地将其转换为时间增量?
现在,我唯一的方法是使用此正则表达式(\d*)h?(\d*)m?(\d*)s?
这给了我[1-3]个小组。
然后我可以将其翻译为
class MaxTimeField(pw.CharField):
def db_value(self, value):
times = re.search(TIME_DELTA, value)
times = str(
timedelta(
**{
"hours": int(times.group(1) or 0),
"minutes": int(times.group(2) or 0),
"seconds": int(times.group(3) or 0),
}
)
)
return super().db_value(times)
... 如果该组存在。我觉得可能有些东西可以很好地做到这一点,但我找不到。如果有更优雅的方法,我想避免使用正则表达式。我希望提出建议。
答案 0 :(得分:1)
您使用的技术没有任何问题。您的代码看起来不错,但我想不可避免地需要探索一些小技巧。
请考虑在函数外部定义time_re = re.compile(r'(\d*)h?(\d*)m?(\d*)s?')
,并使用time_re.search(value)
对其进行引用。该函数被调用了很多次,但是正则表达式只需要编译一次。
在使用\d*
的地方,我可能会选择\d+
,尽管or 0
表达式表明如果缺少字段,可能会遇到麻烦。我 am 担心输入'9h24s'。
考虑用h, m, s = times.groups()
拆包,然后构造dict(hours=h, minutes=m, seconds=s)
。这只是另一种样式,它避免了1,2,3参数。
考虑使用稍微更“忙”(或至少稍长)的正则表达式:
time_re = re.compile(r'(?P<hours>\d*)h?(?P<minutes>\d*)m?(?P<seconds>\d*)s?')
d = time_re.search(value).groupdict()
那时每个字典d
的值都是一个字符串,因此在处理空字符串时,您仍然需要转换为整数。
诸如[('h', 3600), ('m', 60), ('s', 1)]
之类的列表将使您完全放弃正则表达式,并累积总秒数。每对的第一个元素是unit
。如果字符串中包含unit
,则字符串中包含.split()
,转换为int
,并累积乘积。