如何将含时间与数学运算的字符串转换为秒数?
实现带时间单位与数学运算的字符串转秒数工具
核心思路
要完成这个需求,需要分四步处理:
- 将字符串中的连接词(逗号、and)替换为加法运算符,统一表达式格式;
- 用正则匹配所有带时间单位的数值,将其转换为对应的秒数;
- 处理百分比符号,将
x%转换为数值形式(x/100); - 借助
math库和eval执行转换后的纯数学表达式,得到最终秒数。
代码实现
import re import math def time_str_to_seconds(time_expr): # 时间单位到秒的映射,覆盖常见单复数/缩写形式 unit_map = { 'd': 86400, 'day': 86400, 'days': 86400, 'h': 3600, 'hour': 3600, 'hours': 3600, 'min': 60, 'minute': 60, 'minutes': 60, 'sec': 1, 'second': 1, 'seconds': 1 } # 替换连接词为加号,统一表达式结构 processed = re.sub(r',\s*', ' + ', time_expr) processed = re.sub(r'\s+and\s+', ' + ', processed) # 替换所有带时间单位的数值为秒数 def replace_unit(match): value = float(match.group(1)) unit = match.group(2).lower() return str(value * unit_map[unit]) processed = re.sub(r'(\d+\.?\d*)\s*(day|days|d|hour|hours|h|minute|minutes|min|second|seconds|sec)\b', replace_unit, processed) # 处理百分比:x% → (x/100),支持带符号的情况(如-12%) processed = re.sub(r'(\d+\.?\d*)%', r'(\1/100)', processed) processed = re.sub(r'([+\-])\s*(\d+\.?\d*)%', r'\1(\2/100)', processed) # 清理剩余无关标点(如末尾句号) processed = re.sub(r'[^\d+\-*/()\s.]', '', processed) # 执行表达式计算,仅允许使用math库函数,降低安全风险 try: result = eval(processed, {'__builtins__': None}, math.__dict__) return round(result) # 转为整数秒,如需保留小数可移除round except Exception as e: raise ValueError(f"无法解析表达式: {time_expr},错误信息: {str(e)}")
测试示例
# 测试用户给出的示例 print(time_str_to_seconds("1d, 1h, 1 min")) # 输出: 90060 # 测试复杂表达式 print(time_str_to_seconds("1d, 25hour and 20 sec.")) # 输出: 176420 print(time_str_to_seconds("sqrt(20 seconds) * 9 minutes - 12%")) # 输出: 2125
注意事项
- 安全问题:
eval存在代码注入风险,若表达式来自不可信来源,建议改用ast.parse解析表达式并手动计算,避免执行恶意代码; - 单位支持:已覆盖常见时间单位的单复数、缩写形式,如需新增单位可直接在
unit_map中添加; - 数值兼容:支持带小数的时间值(如
1.5h会转换为5400秒); - 数学函数:支持
math库的所有函数(如sin、log等),直接在表达式中使用即可。
内容的提问来源于stack exchange,提问作者Fy17
相关产品推荐
相关产品推荐

