You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用正则表达式解析时长字符串计算总秒数?实现可选部分匹配

解决思路:让时间段分组可选,覆盖所有合法格式

嘿,这个问题我之前刚好折腾过!你原来的正则((\d+)h)((\d+)m)((\d+)s)只能匹配同时包含小时、分钟、秒的完整格式,核心原因是每个时间分组都被写成了必填项——必须同时存在h、m、s部分才能匹配成功。要适配40s、11m1s这类不完整的格式,我们需要给每个时间段的分组加上可选标记,同时确保正则能匹配所有合法的时长组合。

优化后的正则表达式

推荐使用这个正则:

^(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?$

正则各部分解释:

  • ^ 和 $:确保匹配整个字符串,避免出现12h30mxyz这种包含无效字符的情况
  • (?:(\d+)h)?:非捕获组包裹小时部分,?表示这个组可选;内部的(\d+)是捕获组,用来提取小时数
  • (?:(\d+)m)?:同理,可选的分钟部分
  • (?:(\d+)s)?:可选的秒数部分

这个正则可以完美匹配以下所有场景:

  • 仅秒:40s → 捕获组3为40,其余为空
  • 分+秒:11m1s → 捕获组2为11,捕获组3为1
  • 时+分+秒:1h47m3s → 捕获组1为1,捕获组2为47,捕获组3为3
  • 仅时:2h → 捕获组1为2,其余为空
  • 时+秒:3h5s → 捕获组1为3,捕获组3为5(虽然这种格式少见,但正则也能兼容)

更友好的进阶写法:命名捕获组

如果想让代码可读性更高,可以用命名捕获组,这样提取数值时不用记分组索引:

^(?:(?P<hours>\d+)h)?(?:(?P<minutes>\d+)m)?(?:(?P<seconds>\d+)s)?$

计算总秒数的代码示例(以Python为例)

用上面的正则配合代码,就能轻松算出总秒数:

import re

def get_total_seconds(duration):
    # 用命名捕获组的正则
    pattern = r'^(?:(?P<hours>\d+)h)?(?:(?P<minutes>\d+)m)?(?:(?P<seconds>\d+)s)?$'
    match_result = re.match(pattern, duration.strip())
    
    if not match_result:
        raise ValueError("时长格式无效,请输入类似40s、11m1s、1h47m3s的格式")
    
    # 提取各部分数值,为空则默认0
    hours = int(match_result.group('hours')) if match_result.group('hours') else 0
    minutes = int(match_result.group('minutes')) if match_result.group('minutes') else 0
    seconds = int(match_result.group('seconds')) if match_result.group('seconds') else 0
    
    return hours * 3600 + minutes * 60 + seconds

# 测试几个例子
print(get_total_seconds("40s"))          # 输出:40
print(get_total_seconds("11m1s"))        # 输出:661
print(get_total_seconds("1h47m3s"))      # 输出:6423

额外小技巧

如果需要兼容大小写格式(比如1H2M3S),可以在匹配时加上忽略大小写的标志:

match_result = re.match(pattern, duration.strip(), re.IGNORECASE)

内容的提问来源于stack exchange,提问作者Ituhimux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:47:07