匹配小时-分钟-秒 (hms) 持续时间字符串

Matching hour-minute-second (hms) duration string

我想将 hms 之前的数字匹配到它们各自的捕获组中。如果可能的话,我想匹配所有 3 个组。如果缺少一个或两个其他组,则匹配最后一个组。

如下图和 regex101 中所示,我目前的正则表达式为
/(\d+)(?=h)|(\d+)(?=m)|(\d+)(?=s)/g,对于我的测试字符串,匹配 12 场比赛,每场比赛 1 组。

但是 I want 7 个匹配项。第一个匹配包含 3 个组,2:nd 到 4:th 匹配每个包含 2 个组,最后 3 个匹配每个包含一个组。

所以I want:

  1. 匹配 1:11h22m33s
    1. 第 1 组:11
    2. 第 2 组:22
    3. 第 3 组:33
  2. 第 2 场:11h22m
    1. 第 1 组:11
    2. 第 2 组:22
  3. 第 3 场:11h33s
    1. 第 1 组:11
    2. 第 2 组:33
  4. 第 4 场:22m33s
    1. 第 1 组:22
    2. 第 2 组:33
  5. 第 5 场:11h
    1. 第 1 组:11
  6. 第 6 场:22m
    1. 第 1 组:22
  7. 第 7 场:33s
    1. 第 1 组:33

编辑

测试字符串可以包含在其他字符串中!例如。 08:00 + 11h。参见 https://regex101.com/r/RWA9Oy/1

如果你需要确保整个字符串匹配模式,你可以使用

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

参见regex demo

如果需要从较长的文本中提取这些字符串,可以使用

\b(?=\w)(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?\b(?!\w)

参见 this regex demo

详情:

  • ^ - 字符串开头
  • (?!$) - 字符串不能在开头结束(=不能为空)
  • \b(?=\w) - 一个单词边界,右边的字符是单词字符(=是字母、数字或 _
  • (?:(\d+)h)? - 一个可选的 non-capturing 组匹配一个或多个数字(将它们捕获到第 1 组)和一个 h 字母
  • (?:(\d+)m)? - 一个可选的 non-capturing 组匹配一个或多个数字(将它们捕获到第 2 组)和一个 m 字母
  • (?:(\d+)s)? - 一个可选的 non-capturing 组匹配一个或多个数字(将它们捕获到第 3 组)和一个 s 字母
  • $ - 字符串结尾
  • \b(?!\w) - 一个单词边界,其中右侧的字符不是单词字符或字符串末尾。

以防万一您希望组件之间有任意数量的空格,您可以添加 \s*:

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

或者,对于部分匹配

\b(?=\w)(?:(\d+)\s*h\s*)?(?:(\d+)\s*m\s*)?(?:(\d+)\s*s)?\b(?!\w)

this regex demo and another regex demo